hslua-packaging 2.0.0 → 2.1.0
raw patch · 18 files changed
+535/−163 lines, 18 filesdep ~hslua-coredep ~hslua-marshallingdep ~hslua-objectorientationPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hslua-core, hslua-marshalling, hslua-objectorientation, text
API changes (from Hackage documentation)
- HsLua.Packaging.Function: docsField :: Name
- HsLua.Packaging.Function: pushDocumentation :: LuaError e => StackIndex -> LuaE e NumResults
+ HsLua.Packaging.Convenience: boolParam :: Text -> Text -> Parameter e Bool
+ HsLua.Packaging.Convenience: boolResult :: Text -> FunctionResults e Bool
+ HsLua.Packaging.Convenience: integralParam :: (Read a, Integral a) => Text -> Text -> Parameter e a
+ HsLua.Packaging.Convenience: integralResult :: (Integral a, Show a) => Text -> FunctionResults e a
+ HsLua.Packaging.Convenience: stringParam :: Text -> Text -> Parameter e String
+ HsLua.Packaging.Convenience: stringResult :: Text -> FunctionResults e String
+ HsLua.Packaging.Convenience: textParam :: Text -> Text -> Parameter e Text
+ HsLua.Packaging.Convenience: textResult :: Text -> FunctionResults e Text
+ HsLua.Packaging.Documentation: docsField :: Name
+ HsLua.Packaging.Documentation: documentation :: LuaError e => DocumentedFunction e
+ HsLua.Packaging.Documentation: getdocumentation :: LuaError e => StackIndex -> LuaE e Type
+ HsLua.Packaging.Documentation: pushFieldDoc :: LuaError e => Pusher e (Field e)
+ HsLua.Packaging.Documentation: pushFunctionDoc :: LuaError e => Pusher e (DocumentedFunction e)
+ HsLua.Packaging.Documentation: pushModuleDoc :: LuaError e => Pusher e (Module e)
+ HsLua.Packaging.Documentation: registerDocumentation :: LuaError e => StackIndex -> LuaE e ()
+ HsLua.Packaging.Function: data HsFnPrecursor e a
+ HsLua.Packaging.Function: opt :: Parameter e a -> Parameter e (Maybe a)
+ HsLua.Packaging.Function: returnResults :: HsFnPrecursor e (LuaE e a) -> FunctionResults e a -> DocumentedFunction e
+ HsLua.Packaging.Function: updateFunctionDescription :: DocumentedFunction e -> Text -> DocumentedFunction e
+ HsLua.Packaging.UDType: udresult :: LuaError e => DocumentedTypeWithList e a itemtype -> Text -> FunctionResults e a
- HsLua.Packaging.UDType: alias :: Name -> Text -> [AliasIndex] -> Member e fn a
+ HsLua.Packaging.UDType: alias :: AliasIndex -> Text -> [AliasIndex] -> Member e fn a
Files
- CHANGELOG.md +67/−14
- LICENSE +1/−1
- hslua-packaging.cabal +11/−6
- src/HsLua/Packaging.hs +7/−5
- src/HsLua/Packaging/Convenience.hs +74/−0
- src/HsLua/Packaging/Documentation.hs +159/−0
- src/HsLua/Packaging/Function.hs +24/−56
- src/HsLua/Packaging/Module.hs +42/−9
- src/HsLua/Packaging/Rendering.hs +2/−1
- src/HsLua/Packaging/Types.hs +1/−1
- src/HsLua/Packaging/UDType.hs +9/−1
- test/HsLua/Packaging/DocumentationTests.hs +51/−0
- test/HsLua/Packaging/FunctionTests.hs +20/−14
- test/HsLua/Packaging/ModuleTests.hs +58/−50
- test/HsLua/Packaging/RenderingTests.hs +4/−2
- test/HsLua/Packaging/UDTypeTests.hs +1/−1
- test/HsLua/PackagingTests.hs +3/−1
- test/test-hslua-packaging.hs +1/−1
CHANGELOG.md view
@@ -1,22 +1,75 @@-## Changelog+# Changelog -`hslua-packaging` uses [PVP Versioning](https://pvp.haskell.org).+`hslua-packaging` uses [PVP Versioning][]. -### hslua-packaging 2.0.0+## hslua-packaging-2.1.0 -Release pending.+Released 29-01-2022. -- Initially created. Contains modules previously found in the- modules `Foreign.Lua.Call` and `Foreign.Lua.Module` from- `hslua-1.3`.+- Added function `documentation`: The documented function+ `documentation` is added and exported from module+ `HsLua.Packaging.Documentation`. It allows to retrieve the+ documentation of a given Lua object. -- Moved module hierarchy from Foreign.Lua to HsLua.+ This replaces `pushDocumentationFunction`, which was removed. -- Added support for a "since" tag on documented functions; allows- to mark the library version when a function was introduced in- its present form.+- Cleanup of Function module: -- Improved syntax for the creation of documented functions.+ - `docsField` was moved to module Documentation.+ - `pushDocumentation` is renamed to `getdocumentation` and+ moved to the Documentation module. It now returns the Lua+ type of the retrieved documentation value. -- Documentation for functions is now stored in Lua; a method to- access it is available as a HaskellFunction.+- Function `registerDocumentation` was changed: the documentation+ is no longer passed in but must be at the top of the stack.++- New functions `pushModuleDoc`, and `pushFunctionDoc`, pushing+ structured documentation objects for models and functions,+ respectively.++- Provide function `opt` to make a parameter optional. The+ function `optionalParameter` is deprecated, use `opt+ (parameter ...)` instead.++- Added function `udresult`; it defines a function result and is+ analogous to the existing `udparam` function.++- Added module `Convenience`, which defines many functions to+ make the definition of parameters and results easier for+ the most common types.++- Pushing a documented module now also registers the module's+ documentation.++- The module HsLua.Packaging.Rendering has been deprecated. It+ is no longer exported as part of HsLua.Packaging and must be+ imported explicitly if needed. It may be removed in the+ future. Use Lua objects retrievable with `getdocumentation`+ together with a custom renderer instead.++- Update to hslua-objectorientation-2.1.0. Lists are now+ writable. This entails a change to `deftype'`. See the+ changelog of hslua-objectorientation for details.++- Update to hslua-core 2.1.0 and hslua-marshalling 2.1.0.++## hslua-packaging-2.0.0++Released 2021-10-21.++- Initially created. Contains modules previously found in the+ modules `Foreign.Lua.Call` and `Foreign.Lua.Module` from+ `hslua-1.3`.++- Moved module hierarchy from Foreign.Lua to HsLua.++- Added support for a “since” tag on documented functions;+ allows to mark the library version when a function was+ introduced in its present form.++- Improved syntax for the creation of documented functions.++- Documentation for functions is now stored in Lua; a method to+ access it is available as a HaskellFunction.++ [PVP Versioning]: https://pvp.haskell.org
LICENSE view
@@ -1,4 +1,4 @@-Copyright © 2019-2021 Albert Krewinkel+Copyright © 2019-2022 Albert Krewinkel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
hslua-packaging.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: hslua-packaging-version: 2.0.0+version: 2.1.0 synopsis: Utilities to build Lua modules. description: Utilities to package up Haskell functions and values into a Lua module.@@ -14,7 +14,7 @@ license-file: LICENSE author: Albert Krewinkel maintainer: albert+hslua@zeitkraut.de-copyright: © 2019-2021 Albert Krewinkel+copyright: © 2019-2022 Albert Krewinkel category: Foreign extra-source-files: README.md , CHANGELOG.md@@ -25,6 +25,7 @@ , GHC == 8.8.4 , GHC == 8.10.3 , GHC == 9.0.1+ , GHC == 9.2.1 source-repository head type: git@@ -34,11 +35,11 @@ common common-options default-language: Haskell2010 build-depends: base >= 4.8 && < 5- , hslua-core >= 2.0 && < 2.1- , hslua-marshalling >= 2.0 && < 2.1- , hslua-objectorientation >= 2.0 && < 2.1+ , hslua-core >= 2.1 && < 2.2+ , hslua-marshalling >= 2.1 && < 2.2+ , hslua-objectorientation >= 2.1 && < 2.2 , mtl >= 2.2 && < 2.3- , text >= 1.0 && < 1.3+ , text >= 1.2 && < 2.1 ghc-options: -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances@@ -55,6 +56,8 @@ library import: common-options exposed-modules: HsLua.Packaging+ , HsLua.Packaging.Convenience+ , HsLua.Packaging.Documentation , HsLua.Packaging.Function , HsLua.Packaging.Module , HsLua.Packaging.Rendering@@ -62,6 +65,7 @@ , HsLua.Packaging.UDType hs-source-dirs: src default-extensions: LambdaCase+ , StrictData other-extensions: DeriveFunctor , OverloadedStrings build-depends: containers >= 0.5.9 && < 0.7@@ -73,6 +77,7 @@ hs-source-dirs: test ghc-options: -threaded other-modules: HsLua.PackagingTests+ , HsLua.Packaging.DocumentationTests , HsLua.Packaging.FunctionTests , HsLua.Packaging.ModuleTests , HsLua.Packaging.RenderingTests
src/HsLua/Packaging.hs view
@@ -1,25 +1,27 @@ {-| Module : HsLua.Packaging-Copyright : © 2019-2021 Albert Krewinkel+Copyright : © 2019-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> -Tools to create Lua modules.+Tools to create documented Lua functions and modules. -} module HsLua.Packaging ( -- * Modules module HsLua.Packaging.Module , module HsLua.Packaging.Function+ , module HsLua.Packaging.Convenience -- * Object oriented marshalling , module HsLua.Packaging.UDType- -- * Create documentation- , module HsLua.Packaging.Rendering+ -- * Register and access docs in Lua+ , module HsLua.Packaging.Documentation -- * Types , module HsLua.Packaging.Types ) where +import HsLua.Packaging.Convenience+import HsLua.Packaging.Documentation import HsLua.Packaging.Function import HsLua.Packaging.Module-import HsLua.Packaging.Rendering import HsLua.Packaging.UDType import HsLua.Packaging.Types
+ src/HsLua/Packaging/Convenience.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE OverloadedStrings #-}+{-|+Module : HsLua.Packaging.Convenience+Copyright : © 2021-2022 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>++Convenience functions for common parameter and result types.+-}+module HsLua.Packaging.Convenience+where++import Data.Text (Text)+import HsLua.Marshalling+import HsLua.Packaging.Function++-- * Parameters++-- | Defines a function parameter of type 'Bool'.+boolParam :: Text -- ^ parameter name+ -> Text -- ^ parameter description+ -> Parameter e Bool+boolParam = parameter peekBool "boolean"+{-# INLINE boolParam #-}++-- | Defines a function parameter for an integral type.+integralParam :: (Read a, Integral a)+ => Text -- ^ parameter name+ -> Text -- ^ parameter description+ -> Parameter e a+integralParam = parameter peekIntegral "integer"+{-# INLINE integralParam #-}++-- | Defines a function parameter of type 'String'.+stringParam :: Text -- ^ parameter name+ -> Text -- ^ parameter description+ -> Parameter e String+stringParam = parameter peekString "string"+{-# INLINE stringParam #-}++-- | Defines a function parameter of type 'Text'.+textParam :: Text -- ^ parameter name+ -> Text -- ^ parameter description+ -> Parameter e Text+textParam = parameter peekText "string"+{-# INLINE textParam #-}+++-- * Results++-- | Defines a function result of type 'Bool'.+boolResult :: Text -- ^ result description+ -> FunctionResults e Bool+boolResult = functionResult pushBool "boolean"+{-# INLINE boolResult #-}++-- | Defines a function result for an integral type.+integralResult :: (Integral a, Show a)+ => Text -- ^ result description+ -> FunctionResults e a+integralResult = functionResult pushIntegral "integer|string"+{-# INLINE integralResult #-}++-- | Defines a function result of type 'Text'.+stringResult :: Text -- ^ result description+ -> FunctionResults e String+stringResult = functionResult pushString "string"+{-# INLINE stringResult #-}++-- | Defines a function result of type 'Text'.+textResult :: Text -- ^ result description+ -> FunctionResults e Text+textResult = functionResult pushText "string"+{-# INLINE textResult #-}
+ src/HsLua/Packaging/Documentation.hs view
@@ -0,0 +1,159 @@+{-# LANGUAGE OverloadedStrings #-}+{-|+Module : HsLua.Packaging.Documentation+Copyright : © 2020-2022 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>++Provides a function to print documentation if available.+-}+module HsLua.Packaging.Documentation+ ( documentation+ , getdocumentation+ , registerDocumentation+ , pushModuleDoc+ , pushFunctionDoc+ , pushFieldDoc+ , docsField+ ) where++import Data.Version (showVersion)+import HsLua.Core as Lua+import HsLua.Marshalling+import HsLua.Packaging.Types++-- | Function that retrieves documentation.+documentation :: LuaError e => DocumentedFunction e+documentation =+ DocumentedFunction+ { callFunction = documentationHaskellFunction+ , functionName = "documentation"+ , functionDoc = FunctionDoc+ { functionDescription =+ "Retrieves the documentation of the given object."+ , parameterDocs =+ [ ParameterDoc+ { parameterName = "value"+ , parameterType = "any"+ , parameterDescription = "documented object"+ , parameterIsOptional = False+ }+ ]+ , functionResultsDocs = ResultsDocList+ [ ResultValueDoc "string|nil" "docstring" ]+ , functionSince = Nothing+ }+ }++-- | Function that returns the documentation of a given object, or @nil@+-- if no documentation is available.+documentationHaskellFunction :: LuaError e => LuaE e NumResults+documentationHaskellFunction = isnoneornil (nthBottom 1) >>= \case+ True -> failLua "expected a non-nil value as argument 1"+ _ -> NumResults 1 <$ getdocumentation top++-- | Pushes the documentation for the element at the given stack index.+-- Returns the type of the documentation object.+getdocumentation :: LuaError e => StackIndex -> LuaE e Lua.Type+getdocumentation idx = do+ idx' <- absindex idx+ pushDocumentationTable+ pushvalue idx'+ rawget (nth 2) <* Lua.remove (nth 2) -- remove documentation table++-- | Registers the object at the top of the stack as documentation for+-- the object at index @idx@. Pops the documentation of the stack.+registerDocumentation :: LuaError e+ => StackIndex -- ^ @idx@+ -> LuaE e ()+registerDocumentation idx = do+ checkstack' 10 "registerDocumentation" -- keep some buffer+ idx' <- absindex idx+ pushDocumentationTable+ pushvalue idx' -- the documented object+ pushvalue (nth 3) -- documentation object+ rawset (nth 3) -- add to docs table+ pop 2 -- docs table and documentation object++-- | Pushes the documentation table that's stored in the registry to the+-- top of the stack, creating it if necessary. The documentation table+-- is indexed by the documented objects, like module tables and+-- functions, and contains documentation strings as values.+--+-- The table is an ephemeron table, i.e., an entry gets garbage+-- collected if the key is no longer reachable.+pushDocumentationTable :: LuaError e => LuaE e ()+pushDocumentationTable = Lua.getfield registryindex docsField >>= \case+ Lua.TypeTable -> return () -- documentation table already initialized+ _ -> do+ pop 1 -- pop non-table value+ newtable -- create documentation table+ pushstring "k" -- Make it an "ephemeron table" and..+ setfield (nth 2) "__mode" -- collect docs if documented object is GCed+ pushvalue top -- add copy of table to registry+ setfield registryindex docsField++-- | Name of the registry field holding the documentation table. The+-- documentation table is indexed by the documented objects, like module+-- tables and functions, and contains documentation strings as values.+--+-- The table is an ephemeron table, i.e., an entry gets garbage+-- collected if the key is no longer reachable.+docsField :: Name+docsField = "HsLua docs"++-- | Pushes the documentation of a module as a table with string fields+-- @name@ and @description@.+pushModuleDoc :: LuaError e => Pusher e (Module e)+pushModuleDoc = pushAsTable+ [ ("name", pushName . moduleName)+ , ("description", pushText . moduleDescription)+ , ("fields", pushList pushFieldDoc . moduleFields)+ , ("functions", pushList pushFunctionDoc . moduleFunctions)+ ]++-- | Pushes the documentation of a field as a table with string fields+-- @name@ and @description@.+pushFieldDoc :: LuaError e => Pusher e (Field e)+pushFieldDoc = pushAsTable+ [ ("name", pushText . fieldName)+ , ("description", pushText . fieldDescription)+ ]++-- | Pushes the documentation of a function as a table with string+-- fields, @name@, @description@, and @since@, sequence field+-- @parameters@, and sequence or string field @results@.+pushFunctionDoc :: LuaError e => Pusher e (DocumentedFunction e)+pushFunctionDoc fun = pushAsTable+ [ ("name", pushName . const (functionName fun))+ , ("description", pushText . functionDescription)+ , ("parameters", pushList pushParameterDoc . parameterDocs)+ , ("results", pushResultsDoc . functionResultsDocs)+ , ("since", maybe pushnil (pushString . showVersion) . functionSince)+ ] (functionDoc fun)++-- | Pushes the documentation of a parameter as a table with boolean+-- field @optional@ and string fields @name@, @type@, and @description.+pushParameterDoc :: LuaError e => Pusher e ParameterDoc+pushParameterDoc = pushAsTable+ [ ("name", pushText . parameterName)+ , ("type", pushText . parameterType)+ , ("description", pushText . parameterDescription)+ , ("optional", pushBool . parameterIsOptional)+ ]++-- | Pushes a the documentation for a function's return values as either+-- a simple string, or as a sequence of tables with @type@ and+-- @description@ fields.+pushResultsDoc :: LuaError e => Pusher e ResultsDoc+pushResultsDoc = \case+ ResultsDocMult desc -> pushText desc+ ResultsDocList resultDocs -> pushList pushResultValueDoc resultDocs++-- | Pushes the documentation of a single result value as a table with+-- fields @type@ and @description@.+pushResultValueDoc :: LuaError e => Pusher e ResultValueDoc+pushResultValueDoc = pushAsTable+ [ ("type", pushText . resultValueType)+ , ("description", pushText . resultValueDescription)+ ]
src/HsLua/Packaging/Function.hs view
@@ -4,7 +4,7 @@ {-# LANGUAGE OverloadedStrings #-} {-| Module : HsLua.Packaging.Function-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> Stability : alpha@@ -19,7 +19,9 @@ , lambda , applyParameter , returnResult+ , returnResults , returnResultsOnStack+ , updateFunctionDescription , liftPure , liftPure2 , liftPure3@@ -40,14 +42,13 @@ , since -- * Pushing to Lua , pushDocumentedFunction- -- * Accessing documentation in Lua- , docsField- , pushDocumentation -- * Convenience functions , parameter+ , opt , optionalParameter , functionResult -- * Internal+ , HsFnPrecursor , toHsFnPrecursor ) where @@ -57,7 +58,7 @@ import Data.Version (Version) import HsLua.Core import HsLua.Marshalling-import HsLua.Packaging.Rendering (renderFunction)+import HsLua.Packaging.Documentation import HsLua.Packaging.Types import qualified HsLua.Core as Lua import qualified HsLua.Core.Utf8 as Utf8@@ -162,7 +163,7 @@ let i = hsFnMaxParameterIdx bldr + 1 let context = Name . Utf8.fromText $ "function argument " <> (parameterName . parameterDoc) param- let nextAction f = withContext context $ do+ let nextAction f = retrieving context $ do !x <- parameterPeeker param i return $ f x bldr@@ -287,52 +288,15 @@ -- Push to Lua -- --- | Name of the registry field holding the documentation table. The--- documentation table is indexed by the documented objects, like module--- tables and functions, and contains documentation strings as values.------ The table is an ephemeron table, i.e., an entry gets garbage--- collected if the key is no longer reachable.-docsField :: Name-docsField = "HsLua docs"- -- | Pushes a documented Haskell function to the Lua stack, making it -- usable as a normal function in Lua. At the same time, the function -- docs are registered in the documentation table. pushDocumentedFunction :: LuaError e => DocumentedFunction e -> LuaE e () pushDocumentedFunction fn = do- -- push function- Lua.pushHaskellFunction $ callFunction fn-- -- store documentation- Lua.getfield registryindex docsField >>= \case- TypeTable -> return () -- already have the documentation table- _ -> do- Lua.pop 1 -- pop non-table value- Lua.newtable -- create documentation table- Lua.pushstring "k" -- Make it an "ephemeron table" and..- Lua.setfield (nth 2) "__mode" -- collect docs if function is GCed- Lua.pushvalue top -- add copy of table to registry- Lua.setfield registryindex docsField- Lua.pushvalue (nth 2) -- the function- pushText $ renderFunction fn- Lua.rawset (nth 3)- Lua.pop 1 -- pop doc table, leave function on stack---- | Pushes the documentation of the object at the given index to the--- stack, or just *nil* if no documentation is available.-pushDocumentation :: LuaError e => StackIndex -> LuaE e NumResults-pushDocumentation idx = do- idx' <- Lua.absindex idx- Lua.getfield registryindex docsField >>= \case- TypeTable -> do- Lua.pushvalue idx'- Lua.rawget (nth 2)- _ -> do -- no documentation table available- Lua.pop 1 -- pop contents of docsField- Lua.pushnil- return (NumResults 1)+ Lua.pushHaskellFunction $ callFunction fn -- push function+ pushFunctionDoc fn -- function documentation+ registerDocumentation (Lua.nth 2) -- store documentation -- -- Convenience functions@@ -354,22 +318,26 @@ } } +-- | Makes a parameter optional.+opt :: Parameter e a -> Parameter e (Maybe a)+opt p = Parameter+ { parameterPeeker = \idx ->+ (Nothing <$ peekNoneOrNil idx) <|>+ (Just <$!> parameterPeeker p idx)+ , parameterDoc = (parameterDoc p){ parameterIsOptional = True }+ }+ -- | Creates an optional parameter.+--+-- DEPRECATED: Use @opt (parameter ...)@ instead. optionalParameter :: Peeker e a -- ^ method to retrieve the value from Lua -> Text -- ^ expected Lua type -> Text -- ^ parameter name -> Text -- ^ parameter description -> Parameter e (Maybe a)-optionalParameter peeker type_ name desc = Parameter- { parameterPeeker = \idx -> (Nothing <$ peekNoneOrNil idx)- <|> (Just <$!> peeker idx)- , parameterDoc = ParameterDoc- { parameterName = name- , parameterDescription = desc- , parameterType = type_- , parameterIsOptional = True- }- }+optionalParameter peeker type_ name desc = opt $+ parameter peeker type_ name desc+{-# DEPRECATED optionalParameter "Use `opt (parameter ...)` instead." #-} -- | Creates a function result. functionResult :: Pusher e a -- ^ method to push the Haskell result to Lua
src/HsLua/Packaging/Module.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-| Module : HsLua.Packaging.Module-Copyright : © 2019-2021 Albert Krewinkel+Copyright : © 2019-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <albert+hslua@zeitkraut.de> Stability : alpha@@ -23,10 +23,11 @@ import Control.Monad (forM_) import HsLua.Core-import HsLua.Marshalling (pushName, pushText)+import HsLua.Marshalling (pushAsTable, pushList, pushName, pushText) import HsLua.ObjectOrientation.Operation (Operation (..), metamethodName)+import HsLua.Packaging.Documentation import HsLua.Packaging.Types-import qualified HsLua.Packaging.Function as Call+import qualified HsLua.Packaging.Function as Fun -- | Create a new module (i.e., a Lua table). create :: LuaE e ()@@ -36,7 +37,7 @@ -- the stack. registerModule :: LuaError e => Module e -> LuaE e () registerModule mdl =- requirehs (moduleName mdl) (pushModule mdl)+ requirehs (moduleName mdl) (const (pushModule mdl)) -- | Add the module under a different name to the table of preloaded -- packages.@@ -54,11 +55,43 @@ -- | Pushes a documented module to the Lua stack. pushModule :: LuaError e => Module e -> LuaE e () pushModule mdl = do- create- forM_ (moduleFunctions mdl) $ \fn -> do+ checkstack' 10 "pushModule"+ pushAsTable+ [ ("name", pushName . moduleName)+ , ("description", pushText . moduleDescription)+ , ("fields", pushList pushFieldDoc . moduleFields)+ ] mdl+ create -- module table+ pushvalue (nth 2) -- push documentation object+ registerDocumentation (nth 2) -- set and pop doc++ -- # Functions+ --+ -- module table now on top+ -- documentation table in pos 2+ newtable -- function documention+ pushName "functions"+ pushvalue (nth 2)+ rawset (nth 5)+ -- function documentation table now on top+ -- module table in position 2+ -- module documentation table in pos 3+ forM_ (zip [1..] (moduleFunctions mdl)) $ \(i, fn) -> do+ -- push documented function, thereby registering the function docs+ Fun.pushDocumentedFunction fn+ -- add function to module pushName (functionName fn)- Call.pushDocumentedFunction fn- rawset (nth 3)+ pushvalue (nth 2) -- C function+ rawset (nth 5) -- module table+ -- set documentation+ _ <- getdocumentation top+ rawseti (nth 3) i+ pop 1 -- C Function+ pop 1 -- function documentation table+ remove (nth 2) -- module documentation table++ -- # Fields+ -- forM_ (moduleFields mdl) $ \field -> do pushText (fieldName field) fieldPushValue field@@ -70,6 +103,6 @@ newtable forM_ ops $ \(op, fn) -> do pushName $ metamethodName op- Call.pushDocumentedFunction $ Call.setName "" fn+ Fun.pushDocumentedFunction $ Fun.setName "" fn rawset (nth 3) setmetatable (nth 2)
src/HsLua/Packaging/Rendering.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-| Module : HsLua.Packaging.Rendering-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> Stability : alpha@@ -12,6 +12,7 @@ Render function and module documentation. -} module HsLua.Packaging.Rendering+ {-# DEPRECATED "Use getdocumentation with a custom renderer." #-} ( -- * Documentation render , renderModule
src/HsLua/Packaging/Types.hs view
@@ -1,6 +1,6 @@ {-| Module : HsLua.Packaging.Types-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> Stability : alpha
src/HsLua/Packaging/UDType.hs view
@@ -1,6 +1,6 @@ {-| Module : HsLua.Packaging.UDType-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> @@ -25,6 +25,7 @@ , peekUD , pushUD , udparam+ , udresult -- * Helper types for building , Member , Operation (..)@@ -87,3 +88,10 @@ -> Text -- ^ parameter description -> Parameter e a udparam ty = parameter (peekUD ty) (Utf8.toText . fromName $ udName ty)++-- | Defines a function result of the given type.+udresult :: LuaError e+ => DocumentedTypeWithList e a itemtype -- ^ result type+ -> Text -- ^ result description+ -> FunctionResults e a+udresult ty = functionResult (pushUD ty) (Utf8.toText . fromName $ udName ty)
+ test/HsLua/Packaging/DocumentationTests.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications #-}+{-|+Module : HsLua.Packaging.DocumentationTests+Copyright : © 2021-2022 Albert Krewinkel+License : MIT+Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>++Tests for calling exposed Haskell functions.+-}+module HsLua.Packaging.DocumentationTests (tests) where++import Data.Version (makeVersion)+import HsLua.Core (top, Status (OK), Type (TypeNil, TypeString))+import HsLua.Packaging.Documentation+import HsLua.Packaging.Function+import HsLua.Marshalling (forcePeek, peekIntegral, pushIntegral, peekText)+import Test.Tasty.HsLua ((=:), shouldBeResultOf)+import Test.Tasty (TestTree, testGroup)++import qualified HsLua.Core as Lua++-- | Calling Haskell functions from Lua.+tests :: TestTree+tests = testGroup "Documentation"+ [ testGroup "Function docs"+ [ "retrieves function docs" =:+ "factorial" `shouldBeResultOf` do+ pushDocumentedFunction factorial+ Lua.setglobal (functionName factorial)+ pushDocumentedFunction documentation+ Lua.setglobal "documentation"+ OK <- Lua.dostring "return documentation(factorial)"+ TypeString <- Lua.getfield top "name"+ forcePeek $ peekText top++ , "returns nil for undocumented function" =:+ TypeNil `shouldBeResultOf` do+ pushDocumentedFunction documentation+ Lua.setglobal "documentation"+ OK <- Lua.dostring "return documentation(function () return 1 end)"+ Lua.ltype top+ ]+ ]++factorial :: DocumentedFunction Lua.Exception+factorial = defun "factorial" (liftPure $ \n -> product [1..n])+ <#> parameter (peekIntegral @Integer) "integer" "n" ""+ =#> functionResult pushIntegral "integer or string" "factorial"+ #? "Calculates the factorial of a positive integer."+ `since` makeVersion [1,0,0]
test/HsLua/Packaging/FunctionTests.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeApplications #-} {-| Module : HsLua.Packaging.FunctionTests-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> @@ -13,16 +13,17 @@ import Data.Maybe (fromMaybe) import Data.Version (makeVersion) import HsLua.Core (StackIndex, top)+import HsLua.Packaging.Convenience+import HsLua.Packaging.Documentation (getdocumentation) import HsLua.Packaging.Function import HsLua.Packaging.Types import HsLua.Marshalling ( forcePeek, peekIntegral, peekRealFloat, peekText , pushIntegral, pushRealFloat)-import Test.Tasty.HsLua ((=:), shouldBeResultOf, shouldHoldForResultOf)+import Test.Tasty.HsLua ((=:), shouldBeResultOf) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit ((@=?)) -import qualified Data.Text as T import qualified HsLua.Core as Lua -- | Calling Haskell functions from Lua.@@ -85,19 +86,24 @@ ] , testGroup "documentation access"- [ "pushDocumentation" =:- ("factorial (n)\n" `T.isPrefixOf`) `shouldHoldForResultOf` do+ [ "pushDocumentedFunction pushes one value" =:+ 1 `shouldBeResultOf` do+ oldtop <- Lua.gettop pushDocumentedFunction (factLuaAtIndex 0)- numres <- pushDocumentation top- Lua.liftIO $ numres @=? Lua.NumResults 1- forcePeek $ peekText top+ newtop <- Lua.gettop+ pure (newtop - oldtop) + , "getdocumentation" =:+ "factorial" `shouldBeResultOf` do+ pushDocumentedFunction (factLuaAtIndex 0)+ Lua.TypeTable <- getdocumentation top+ Lua.TypeString <- Lua.getfield top "name"+ forcePeek (peekText top)+ , "undocumented value" =: Lua.TypeNil `shouldBeResultOf` do Lua.pushboolean True- numres <- pushDocumentation top- Lua.liftIO $ numres @=? Lua.NumResults 1- Lua.ltype top+ getdocumentation top ] , testGroup "helpers"@@ -112,7 +118,7 @@ parameterDoc (parameter @Lua.Exception peekText "string" "test" "test param") )- , "optionalParameter doc" =:+ , "optional parameter doc" =: ( ParameterDoc { parameterName = "test" , parameterDescription = "test param"@@ -121,7 +127,7 @@ } @=? parameterDoc- (optionalParameter @Lua.Exception peekText "string" "test" "test param")+ (opt (textParam @Lua.Exception "test" "test param")) ) , "functionResult doc" =: ( [ ResultValueDoc@@ -169,7 +175,7 @@ nroot = defun "nroot" ### liftPure2 nroot' <#> parameter (peekRealFloat @Double) "number" "x" ""- <#> optionalParameter (peekIntegral @Int) "integer" "n" ""+ <#> opt (integralParam @Int "n" "") =#> functionResult pushRealFloat "number" "nth root" where nroot' :: Double -> Maybe Int -> Double
test/HsLua/Packaging/ModuleTests.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeApplications #-} {-| Module : HsLua.Packaging.ModuleTests-Copyright : © 2019-2021 Albert Krewinkel+Copyright : © 2019-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <albert+hslua@zeitkraut.de> Stability : alpha@@ -12,11 +12,14 @@ -} module HsLua.Packaging.ModuleTests (tests) where +import HsLua.Core import HsLua.Marshalling- (Result (Success), peekIntegral, peekString, pushIntegral, pushText, runPeek)+ ( forcePeek, peekFieldRaw, peekIntegral, peekString+ , pushIntegral, pushText)+import HsLua.Packaging.Documentation import HsLua.Packaging.Function import HsLua.Packaging.Module-import Test.Tasty.HsLua ((=:), pushLuaExpr, shouldBeResultOf)+import Test.Tasty.HsLua ((=:), shouldBeResultOf) import Test.Tasty (TestTree, testGroup) import qualified HsLua.Core as Lua@@ -24,43 +27,7 @@ -- | Specifications for Attributes parsing functions. tests :: TestTree tests = testGroup "Module"- [ testGroup "requirehs"- [ "pushes module to stack" =:- 1 `shouldBeResultOf` do- Lua.openlibs- old <- Lua.gettop- Lua.requirehs "foo" (Lua.pushnumber 5.0)- new <- Lua.gettop- return (new - old)-- , "module can be loaded with `require`" =:- let testModule = "string as a module"- in Just testModule `shouldBeResultOf` do- Lua.openlibs- Lua.requirehs "test.module" (Lua.pushstring testModule)- pushLuaExpr "require 'test.module'"- Lua.tostring Lua.top- ]-- , testGroup "preloadhs"- [ "does not modify the stack" =:- 0 `shouldBeResultOf` do- Lua.openlibs- old <- Lua.gettop- Lua.preloadhs "foo" (1 <$ Lua.pushnumber 5.0)- new <- Lua.gettop- return (new - old)-- , "module can be loaded with `require`" =:- let testModule = "string as a module"- in Just testModule `shouldBeResultOf` do- Lua.openlibs- Lua.preloadhs "test.module" (1 <$ Lua.pushstring testModule)- pushLuaExpr "require 'test.module'"- Lua.tostring Lua.top- ]-- , testGroup "creation helpers"+ [ testGroup "creation helpers" [ "create produces a table" =: Lua.TypeTable `shouldBeResultOf` do Lua.newtable@@ -76,22 +43,62 @@ return (new - old) , "call module function" =:- Success 24 `shouldBeResultOf` do+ 24 `shouldBeResultOf` do Lua.openlibs registerModule mymath _ <- Lua.dostring $ mconcat [ "local mymath = require 'mymath'\n" , "return mymath.factorial(4)" ]- runPeek $ peekIntegral @Integer Lua.top+ forcePeek $ peekIntegral @Prelude.Integer Lua.top , "call module as function" =:- Success "call me maybe" `shouldBeResultOf` do+ "call me maybe" `shouldBeResultOf` do Lua.openlibs registerModule mymath _ <- Lua.dostring "return (require 'mymath')()"- runPeek $ peekString Lua.top+ forcePeek $ peekString Lua.top + , "access name in docs" =:+ "mymath" `shouldBeResultOf` do+ Lua.openlibs+ registerModule mymath+ TypeTable <- getdocumentation top+ forcePeek $ peekFieldRaw peekString "name" Lua.top++ , "first function name in docs" =:+ "factorial" `shouldBeResultOf` do+ Lua.openlibs+ registerModule mymath+ TypeTable <- getdocumentation top+ TypeTable <- getfield top "functions"+ TypeTable <- rawgeti top 1+ forcePeek $ peekFieldRaw peekString "name" Lua.top++ , "function doc is shared" =:+ True `shouldBeResultOf` do+ Lua.openlibs+ registerModule mymath+ pushvalue top+ setglobal "mymath"+ -- get doc table via module docs+ TypeTable <- getdocumentation top+ TypeTable <- getfield top "functions"+ TypeTable <- rawgeti top 1+ -- get doc table via function+ OK <- dostring "return mymath.factorial"+ TypeTable <- getdocumentation top+ -- must be the same+ rawequal (nth 1) (nth 3)++ , "first field name in docs" =:+ "unit" `shouldBeResultOf` do+ Lua.openlibs+ registerModule mymath+ TypeTable <- getdocumentation top+ TypeTable <- getfield top "fields"+ TypeTable <- rawgeti top 1+ forcePeek $ peekFieldRaw peekString "name" Lua.top ] ] @@ -99,7 +106,9 @@ mymath = Module { moduleName = "mymath" , moduleDescription = "A math module."- , moduleFields = []+ , moduleFields = [+ Field "unit" "additive unit" (pushinteger 1)+ ] , moduleFunctions = [factorial] , moduleOperations = [ (,) Call $ lambda@@ -115,12 +124,11 @@ <#> factorialParam =#> factorialResult -factorialParam :: Parameter Lua.Exception Integer+factorialParam :: Parameter Lua.Exception Prelude.Integer factorialParam =- parameter (peekIntegral @Integer) "integer"+ parameter peekIntegral "integer" "n" "number for which the factorial is computed" -factorialResult :: FunctionResults Lua.Exception Integer-factorialResult =- functionResult (pushIntegral @Integer) "integer" "factorial"+factorialResult :: FunctionResults Lua.Exception Prelude.Integer+factorialResult = functionResult pushIntegral "integer" "factorial"
test/HsLua/Packaging/RenderingTests.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-}+{-# OPTIONS_GHC -Wno-warnings-deprecations #-} {-| Module : HsLua.Packaging.RenderingTests-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> @@ -12,6 +13,7 @@ import Data.Maybe (fromMaybe) import Data.Version (makeVersion)+import HsLua.Packaging.Convenience import HsLua.Packaging.Function import HsLua.Packaging.Module import HsLua.Packaging.Rendering@@ -91,7 +93,7 @@ nroot :: DocumentedFunction Lua.Exception nroot = defun "nroot" (liftPure2 nroot') <#> parameter (peekRealFloat @Double) "number" "x" ""- <#> optionalParameter (peekIntegral @Int) "integer" "n" ""+ <#> opt (integralParam @Int "n" "") =#> functionResult pushRealFloat "number" "nth root" where nroot' :: Double -> Maybe Int -> Double
test/HsLua/Packaging/UDTypeTests.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE TypeApplications #-} {-| Module : HsLua.Packaging.UDTypeTests-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>
test/HsLua/PackagingTests.hs view
@@ -1,6 +1,6 @@ {-| Module : HsLua.PackagingTests-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de> @@ -9,6 +9,7 @@ module HsLua.PackagingTests (tests) where import Test.Tasty (TestTree, testGroup)+import qualified HsLua.Packaging.DocumentationTests import qualified HsLua.Packaging.FunctionTests import qualified HsLua.Packaging.ModuleTests import qualified HsLua.Packaging.RenderingTests@@ -21,4 +22,5 @@ , HsLua.Packaging.ModuleTests.tests , HsLua.Packaging.RenderingTests.tests , HsLua.Packaging.UDTypeTests.tests+ , HsLua.Packaging.DocumentationTests.tests ]
test/test-hslua-packaging.hs view
@@ -1,6 +1,6 @@ {-| Module : Main-Copyright : © 2020-2021 Albert Krewinkel+Copyright : © 2020-2022 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>