packages feed

haskell-gi 0.25.0 → 0.26.0

raw patch · 13 files changed

+205/−96 lines, 13 filesdep ~basedep ~haskell-gi-basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, haskell-gi-base

API changes (from Hackage documentation)

+ Data.GI.CodeGen.GtkDoc: CTypeRef :: Text -> CRef
+ Data.GI.CodeGen.GtkDoc: MethodRef :: Name -> Text -> CRef
+ Data.GI.CodeGen.GtkDoc: OldFunctionRef :: Text -> CRef
+ Data.GI.CodeGen.GtkDoc: OldPropertyRef :: Text -> Text -> CRef
+ Data.GI.CodeGen.GtkDoc: OldSignalRef :: Text -> Text -> CRef
+ Data.GI.CodeGen.GtkDoc: VFuncRef :: Name -> Text -> CRef
+ Data.GI.CodeGen.SymbolNaming: haddockAttrAnchor :: Text
+ Data.GI.CodeGen.SymbolNaming: haddockSignalAnchor :: Text
- Data.GI.CodeGen.GtkDoc: FunctionRef :: Text -> CRef
+ Data.GI.CodeGen.GtkDoc: FunctionRef :: Name -> CRef
- Data.GI.CodeGen.GtkDoc: PropertyRef :: Text -> Text -> CRef
+ Data.GI.CodeGen.GtkDoc: PropertyRef :: Name -> Text -> CRef
- Data.GI.CodeGen.GtkDoc: SignalRef :: Text -> Text -> CRef
+ Data.GI.CodeGen.GtkDoc: SignalRef :: Name -> Text -> CRef
- Data.GI.CodeGen.GtkDoc: TypeRef :: Text -> CRef
+ Data.GI.CodeGen.GtkDoc: TypeRef :: Name -> CRef

Files

ChangeLog.md view
@@ -1,3 +1,27 @@+### 0.26.0+++ Support for 'HasField' methods, which allows the syntax 'widget.show' or 'widget.add child' for invoking methods using the new [RecordDotSyntax](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0282-record-dot-syntax.rst) in ghc 9.2.+++ And an implicit '?self' parameter for callbacks, for accessing the calling object. See [issue 346](https://github.com/haskell-gi/haskell-gi/issues/346) where this is necessary in practice in gtk4 to use event controllers.+++ Add an 'After' attribute to connect to signals after the default handler on constructors/setters using attribute syntax, similar to [On](https://hackage.haskell.org/package/haskell-gi-base/docs/Data-GI-Base-Attributes.html#t:AttrOp).+++ Add [resolveSignal](https://hackage.haskell.org/package/haskell-gi-base-0.26.0/docs/Data-GI-Base-Signals.html#v:resolveSignal) for showing what an overloaded signal resolves to: `resolveSignal button #notify` will output [GI.GObject.Objects.Object.Object::notify](https://hackage.haskell.org/package/gi-gobject-2.0.27/docs/GI-GObject-Objects-Object.html#g:signal:notify).++### 0.25.0+++ Support non-GObject object attributes.+++ Support for ghc 9.0.1.+++ Improvements in the generated Haddocks.+++ Remove the command line version of the bindings generator.+++ Remove support for non-IsLabel overloading.+++ Add [resolveMethod](https://hackage.haskell.org/package/haskell-gi-base-0.25.0/docs/Data-GI-Base-Overloading.html#v:resolveMethod) for showing what an overloaded method resolves to: `resolveMethod #show widget` will output `GI.Gtk.Objects.Widget.widgetShow`.+ ### 0.24.5  + Fix an accidental double free for GValues, see [issue 320](https://github.com/haskell-gi/haskell-gi/issues/320).
haskell-gi.cabal view
@@ -1,5 +1,5 @@ name:                haskell-gi-version:             0.25.0+version:             0.26.0 synopsis:            Generate Haskell bindings for GObject Introspection capable libraries description:         Generate Haskell bindings for GObject Introspection capable libraries. This includes most notably                      Gtk+, but many other libraries in the GObject ecosystem provide introspection data too.@@ -7,14 +7,12 @@ license:             LGPL-2.1                      -- or above license-file:        LICENSE-author:              Will Thompson,-                     Iñaki García Etxebarria,-                     Jonas Platte-maintainer:          Iñaki García Etxebarria (inaki@blueleaf.cc)+author:              Will Thompson and Iñaki García Etxebarria+maintainer:          Iñaki García Etxebarria (github@the.blueleaf.cc) stability:           Experimental category:            Development build-type:          Custom-tested-with:         GHC == 8.8.1, GHC == 8.10.1+tested-with:         GHC == 8.4.1, GHC == 8.6.1, GHC == 8.8.1, GHC == 8.10.1, GHC == 9.0.1, GHC == 9.2.1 cabal-version:       2.0  extra-source-files: ChangeLog.md@@ -23,7 +21,7 @@  setup-depends:    base >= 4 && <5,    Cabal,-   cabal-doctest >= 1 && <1.1+   cabal-doctest >= 1  source-repository head   type: git@@ -32,8 +30,8 @@ Library   default-language:    Haskell2010   pkgconfig-depends:   gobject-introspection-1.0 >= 1.32, gobject-2.0 >= 2.32-  build-depends:       base >= 4.9 && < 5,-                       haskell-gi-base >= 0.25.0 && <0.26,+  build-depends:       base >= 4.11 && < 5,+                       haskell-gi-base >= 0.26.0 && <0.27,                        Cabal >= 1.24,                        attoparsec >= 0.13,                        containers,@@ -52,9 +50,7 @@                        text >= 1.0    default-extensions: CPP, ForeignFunctionInterface, DoAndIfThenElse, LambdaCase, RankNTypes, OverloadedStrings-  ghc-options:         -Wall -fwarn-incomplete-patterns -fno-warn-name-shadowing--  ghc-options: -Wcompat+  ghc-options:         -Wall -fwarn-incomplete-patterns -fno-warn-name-shadowing -Wcompat    c-sources:           lib/c/enumStorage.c   build-tool-depends:  hsc2hs:hsc2hs
lib/Data/GI/CodeGen/Code.hs view
@@ -952,6 +952,7 @@                 , "import qualified Data.GI.Base.Properties as B.Properties"                 , "import qualified Data.GI.Base.Signals as B.Signals"                 , "import qualified Control.Monad.IO.Class as MIO"+                , "import qualified Data.Coerce as Coerce"                 , "import qualified Data.Text as T"                 , "import qualified Data.ByteString.Char8 as B"                 , "import qualified Data.Map as Map"
lib/Data/GI/CodeGen/Conversions.hsc view
@@ -74,7 +74,6 @@     Free ma <*> b = Free $ (<*> b) <$> ma  instance (Functor f) => Monad (Free f) where-    return = Pure     (Free x) >>= f = Free (fmap (>>= f) x)     (Pure r) >>= f = f r @@ -649,19 +648,17 @@   a <- findAPI t   case a of     Just (APIStruct s) -> if structIsBoxed s-                          then wrapTransient t+                          then wrapTransient                           else fToH t TransferNothing     Just (APIUnion u) -> if unionIsBoxed u-                         then wrapTransient t+                         then wrapTransient                          else fToH t TransferNothing     _ -> fToH t TransferNothing transientToH t transfer = fToH t transfer  -- | Wrap the given transient.-wrapTransient :: Type -> CodeGen e Converter-wrapTransient t = do-  hCon <- typeConName <$> haskellType t-  return $ lambdaConvert $ "B.ManagedPtr.withTransient " <> hCon+wrapTransient :: CodeGen e Converter+wrapTransient = return $ lambdaConvert $ "B.ManagedPtr.withTransient "  unpackCArray :: Text -> Type -> Transfer -> ExcCodeGen Converter unpackCArray length (TCArray False _ _ t) transfer =
lib/Data/GI/CodeGen/CtoHaskellMap.hs view
@@ -21,7 +21,7 @@                             Signal(..)) import Data.GI.CodeGen.ModulePath (dotModulePath) import Data.GI.CodeGen.SymbolNaming (moduleLocation, lowerName, upperName,-                                     signalHaskellName)+                                     signalHaskellName, haddockSignalAnchor) import Data.GI.CodeGen.Util (ucFirst)  -- | Link to an identifier, module, etc.@@ -120,7 +120,7 @@                 Nothing -> let Name ns owner = n                            in ucFirst ns <> owner           in (SignalRef ownerCName sn,-              ModuleLinkWithAnchor (Just sn') mod ("g:signal:" <> sn'))+              ModuleLinkWithAnchor (Just sn') mod (haddockSignalAnchor <> sn'))  -- | Given an optional C type and the API constructor construct the -- list of associated refs.
lib/Data/GI/CodeGen/Haddock.hs view
@@ -34,7 +34,8 @@ import Data.GI.CodeGen.GtkDoc (GtkDoc(..), Token(..), CRef(..), Language(..),                                Link(..), ListItem(..), parseGtkDoc) import Data.GI.CodeGen.Overrides (onlineDocsMap)-import Data.GI.CodeGen.SymbolNaming (lowerSymbol, signalHaskellName)+import Data.GI.CodeGen.SymbolNaming (lowerSymbol, signalHaskellName,+                                     haddockSignalAnchor)  -- | Where is the documentation located with respect to the relevant -- symbol, useful for determining whether we want to start with @|@ or @^@.@@ -81,7 +82,7 @@ formatUnknownCRef _ (ParamRef p) = "/@" <> lowerSymbol p <> "@/" formatUnknownCRef _ (LocalSignalRef s) =   let sn = signalHaskellName s-  in "[" <> sn <> "](#g:signal:" <> sn <> ")"+  in "[" <> sn <> "](#" <> haddockSignalAnchor <> sn <> ")" formatUnknownCRef c2h (SignalRef owner signal) =   case M.lookup (TypeRef owner) c2h of     Nothing -> formatCRef $ owner <> "::" <> signal
lib/Data/GI/CodeGen/OverloadedMethods.hs view
@@ -136,11 +136,11 @@         let callable = fixupCallerAllocates (methodCallable m)         sig <- callableSignature callable (KnownForeignSymbol undefined) WithoutClosures         bline $ "data " <> infoName-        -- This should not happen, since ordinary methods always-        -- have the instance as first argument.-        when (null (signatureArgTypes sig)) $-          error $ "Internal error: too few parameters! " ++ show m-        let (obj:otherTypes) = map snd (signatureArgTypes sig)+        let (obj, otherTypes) = case map snd (signatureArgTypes sig) of+              -- This should not happen, since ordinary methods always+              -- have the instance as first argument.+              [] -> error $ "Internal error: too few parameters! " ++ show m+              (obj':otherTypes') -> (obj', otherTypes')             sigConstraint = "signature ~ (" <> T.intercalate " -> "               (otherTypes ++ [signatureReturnType sig]) <> ")" @@ -160,12 +160,12 @@           line $ "instance O.OverloadedMethodInfo " <> infoName <> " " <> obj             <> " where"           indent $ do-            line $ "overloadedMethodInfo = O.MethodInfo {"+            line $ "overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {"             indent $ do-              line $ "O.overloadedMethodName = \"" <> dbgInfo <> "\","-              line $ "O.overloadedMethodURL = \"" <>+              line $ "O.resolvedSymbolName = \"" <> dbgInfo <> "\","+              line $ "O.resolvedSymbolURL = \"" <>                 hackageLink <> "#v:" <> mangled <> "\""-              line $ "}"+              line $ "})"          export (NamedSubsection MethodSection $ lowerName mn) infoName 
lib/Data/GI/CodeGen/ProjectInfo.hs view
@@ -24,7 +24,7 @@ homepage = "https://github.com/haskell-gi/haskell-gi"  authors :: Text-authors = "Will Thompson, Iñaki García Etxebarria and Jonas Platte"+authors = "Will Thompson and Iñaki García Etxebarria"  maintainers :: Text maintainers = "Iñaki García Etxebarria"
lib/Data/GI/CodeGen/Properties.hs view
@@ -25,11 +25,14 @@ import Data.GI.CodeGen.Haddock (addSectionDocumentation, writeHaddock,                                 RelativeDocPosition(DocBeforeSymbol)) import Data.GI.CodeGen.Inheritance (fullObjectPropertyList, fullInterfacePropertyList)+import Data.GI.CodeGen.ModulePath (dotModulePath) import Data.GI.CodeGen.SymbolNaming (lowerName, upperName, classConstraint,                                      hyphensToCamelCase, qualifiedSymbol,                                      typeConstraint, callbackDynamicWrapper,                                      callbackHaskellToForeign,-                                     callbackWrapperAllocator, safeCast)+                                     callbackWrapperAllocator, safeCast,+                                     hackageModuleLink, moduleLocation,+                                     haddockAttrAnchor) import Data.GI.CodeGen.Type import Data.GI.CodeGen.Util @@ -376,7 +379,8 @@ genOneProperty owner prop = do   let name = upperName owner       cName = (hyphensToCamelCase . propName) prop-      docSection = NamedSubsection PropertySection (lcFirst cName)+      lcAttr = lcFirst cName+      docSection = NamedSubsection PropertySection lcAttr       pName = name <> cName       flags = propFlags prop       writable = PropertyWritable `elem` flags &&@@ -458,6 +462,11 @@                          else [])     it <- infoType owner prop     export docSection it+    api <- findAPIByName owner+    hackageLink <- hackageModuleLink owner+    let qualifiedAttrName = dotModulePath (moduleLocation owner api)+                            <> "." <> lcAttr+        attrInfoURL = hackageLink <> "#" <> haddockAttrAnchor <> lcAttr     bline $ "data " <> it     line $ "instance AttrInfo " <> it <> " where"     indent $ do@@ -480,6 +489,11 @@               else line $ "attrTransfer _ = undefined"             line $ "attrConstruct = " <> constructor             line $ "attrClear = " <> clear+            line $ "dbgAttrInfo = P.Just (O.ResolvedSymbolInfo {"+            indent $ do+              line $ "O.resolvedSymbolName = \"" <> qualifiedAttrName <> "\""+              line $ ", O.resolvedSymbolURL = \"" <> attrInfoURL <> "\""+              line $ "})"  -- | Generate a placeholder property for those cases in which code -- generation failed.
lib/Data/GI/CodeGen/Signal.hs view
@@ -6,7 +6,7 @@  import Control.Monad (forM, forM_, when, unless) -import Data.Maybe (catMaybes)+import Data.Maybe (catMaybes, isJust) #if !MIN_VERSION_base(4,11,0) import Data.Monoid ((<>)) #endif@@ -27,6 +27,7 @@                                 RelativeDocPosition(..), writeHaddock,                                 writeDocumentation,                                 writeArgDocumentation, writeReturnDocumentation)+import Data.GI.CodeGen.ModulePath (dotModulePath) import Data.GI.CodeGen.SymbolNaming import Data.GI.CodeGen.Transfer (freeContainerType) import Data.GI.CodeGen.Type@@ -37,8 +38,8 @@ -- | The prototype of the callback on the Haskell side (what users of -- the binding will see) genHaskellCallbackPrototype :: Text -> Callable -> Text -> ExposeClosures ->-                               Documentation -> ExcCodeGen ()-genHaskellCallbackPrototype subsec cb htype expose doc = group $ do+                               Bool -> Documentation -> ExcCodeGen ()+genHaskellCallbackPrototype subsec cb htype expose isSignal doc = group $ do     let name' = case expose of                   WithClosures -> callbackHTypeWithClosures htype                   WithoutClosures -> htype@@ -65,13 +66,14 @@       line $ returnArrow <> typeShow (io ret)       writeReturnDocumentation cb False -    blank+    when (not isSignal) $ do+      blank -    -- For optional parameters, in case we want to pass Nothing.-    export (NamedSubsection SignalSection subsec) ("no" <> name')-    writeHaddock DocBeforeSymbol (noCallbackDoc name')-    line $ "no" <> name' <> " :: Maybe " <> name'-    line $ "no" <> name' <> " = Nothing"+      -- For optional parameters, in case we want to pass Nothing.+      export (NamedSubsection SignalSection subsec) ("no" <> name')+      writeHaddock DocBeforeSymbol (noCallbackDoc name')+      line $ "no" <> name' <> " :: Maybe " <> name'+      line $ "no" <> name' <> " = Nothing"    where noCallbackDoc :: Text -> Text         noCallbackDoc typeName =@@ -80,16 +82,21 @@  -- | Generate the type synonym for the prototype of the callback on -- the C side. Returns the name given to the type synonym.-genCCallbackPrototype :: Text -> Callable -> Text -> Bool -> CodeGen e Text-genCCallbackPrototype subsec cb name' isSignal = group $ do+genCCallbackPrototype :: Text -> Callable -> Text ->+                         Maybe Text -> CodeGen e Text+genCCallbackPrototype subsec cb name' maybeOwner = group $ do     let ctypeName = callbackCType name'+        isSignal = isJust maybeOwner -    export (NamedSubsection SignalSection subsec) ctypeName-    writeHaddock DocBeforeSymbol ccallbackDoc+    when (not isSignal) $ do+      export (NamedSubsection SignalSection subsec) ctypeName+      writeHaddock DocBeforeSymbol ccallbackDoc      line $ "type " <> ctypeName <> " ="     indent $ do-      when isSignal $ line $ withComment "Ptr () ->" "object"+      maybe (return ())+        (\owner -> line $ withComment ("Ptr " <> owner <> " ->") "object")+        maybeOwner       forM_ (args cb) $ \arg -> do         ht <- foreignType $ argType arg         let ht' = if direction arg /= DirectionIn@@ -98,7 +105,7 @@         line $ typeShow ht' <> " ->"       when (callableThrows cb) $         line "Ptr (Ptr GError) ->"-      when isSignal $ line $ withComment "Ptr () ->" "user_data"+      when (isJust maybeOwner) $ line $ withComment "Ptr () ->" "user_data"       ret <- io <$> case returnType cb of                       Nothing -> return $ con0 "()"                       Just t -> foreignType t@@ -110,14 +117,15 @@     ccallbackDoc = "Type for the callback on the (unwrapped) C side."  -- | Generator for wrappers callable from C-genCallbackWrapperFactory :: Text -> Text -> CodeGen e ()-genCallbackWrapperFactory subsec name' = group $ do+genCallbackWrapperFactory :: Text -> Text -> Bool -> CodeGen e ()+genCallbackWrapperFactory subsec name' isSignal = group $ do     let factoryName = callbackWrapperAllocator name'     writeHaddock DocBeforeSymbol factoryDoc     line "foreign import ccall \"wrapper\""     indent $ line $ factoryName <> " :: " <> callbackCType name'                <> " -> IO (FunPtr " <> callbackCType name' <> ")"-    export (NamedSubsection SignalSection subsec) factoryName+    when (not isSignal) $ do+      export (NamedSubsection SignalSection subsec) factoryName    where factoryDoc :: Text         factoryDoc = "Generate a function pointer callable from C code, from a `"@@ -141,8 +149,8 @@   return (prime drop)  -- | Generator of closures-genClosure :: Text -> Callable -> Text -> Text -> Bool -> CodeGen e ()-genClosure subsec cb callback name isSignal = group $ do+genClosure :: Text -> Callable -> Text -> Text -> CodeGen e ()+genClosure subsec cb callback name = group $ do   let closure = callbackClosureGenerator name   export (NamedSubsection SignalSection subsec) closure   writeHaddock DocBeforeSymbol closureDoc@@ -151,7 +159,7 @@                      <> callbackCType callback <> ")"       line $ closure <> " cb = liftIO $ do"       indent $ do-            wrapped <- genWrappedCallback cb "cb" callback isSignal+            wrapped <- genWrappedCallback cb "cb" callback False             line $ callbackWrapperAllocator callback <> " " <> wrapped                      <> " >>= B.GClosure.newGClosure"   where@@ -267,24 +275,26 @@ -- FunPtr will be freed by someone else (the function registering the -- callback for ScopeTypeCall, or a destroy notifier for -- ScopeTypeNotified).-genCallbackWrapper :: Text -> Callable -> Text -> Bool -> ExcCodeGen ()-genCallbackWrapper subsec cb name' isSignal = group $ do+genCallbackWrapper :: Text -> Callable -> Text ->+                      Maybe Text -> ExcCodeGen ()+genCallbackWrapper subsec cb name' maybeOwner = group $ do   let wrapperName = callbackHaskellToForeign name'       (hInArgs, _) = callableHInArgs cb WithClosures       hOutArgs = callableHOutArgs cb       wrapperDoc = "Wrap a `" <> name' <> "` into a `" <>                    callbackCType name' <> "`."+      isSignal = isJust maybeOwner -  export (NamedSubsection SignalSection subsec) wrapperName-  writeHaddock DocBeforeSymbol wrapperDoc+  when (not isSignal) $ do+    export (NamedSubsection SignalSection subsec) wrapperName+    writeHaddock DocBeforeSymbol wrapperDoc    group $ do-    line $ wrapperName <> " ::"+    line $ wrapperName <> " :: "     indent $ do       if isSignal-      then do-        line $ name' <> " ->"-      else do+        then line $ "GObject a => (a -> " <> name' <> ") ->"+        else do            line $ "Maybe (Ptr (FunPtr " <> callbackCType name' <> ")) ->"            let hType = if callableHasClosures cb                        then callbackHTypeWithClosures name'@@ -295,8 +305,8 @@      let cArgNames = map escapedArgName (args cb)         allArgs = if isSignal-                  then T.unwords $ ["_cb", "_"] <> cArgNames <> ["_"]-                  else T.unwords $ ["funptrptr", "_cb"] <> cArgNames+                  then T.unwords $ ["gi'cb", "gi'selfPtr"] <> cArgNames <> ["_"]+                  else T.unwords $ ["gi'funptrptr", "gi'cb"] <> cArgNames     line $ wrapperName <> " " <> allArgs <> " = do"     indent $ do       hInNames <- forM hInArgs (prepareArgForCall cb)@@ -310,11 +320,18 @@                          []  -> ""                          [r] -> r <> " <- "                          _   -> mkTuple returnVars <> " <- "-      line $ returnBind <> "_cb " <> T.concat (map (" " <>) hInNames) +      if isSignal+      then line $ returnBind+                  <> "B.ManagedPtr.withTransient"+                  <> " gi'selfPtr $ \\gi'self -> "+                  <> "gi'cb (Coerce.coerce gi'self) "+                  <> T.concat (map (" " <>) hInNames)+      else line $ returnBind <> "gi'cb " <> T.concat (map (" " <>) hInNames)+       forM_ hOutArgs saveOutArg -      unless isSignal $ line "maybeReleaseFunPtr funptrptr"+      unless isSignal $ line "maybeReleaseFunPtr gi'funptrptr"        case returnType cb of         Nothing -> return ()@@ -322,7 +339,7 @@            nullableReturnType <- typeIsNullable r            if returnMayBeNull cb && nullableReturnType            then do-             line "maybeM nullPtr result $ \\result' -> do"+             line "maybeM FP.nullPtr result $ \\result' -> do"              indent $ unwrapped "result'"            else unwrapped "result"            where@@ -348,14 +365,14 @@                    line $ "-- XXX Could not generate callback wrapper for "                           <> name'                    printCGError e) $ do-      typeSynonym <- genCCallbackPrototype name' cb' name' False+      typeSynonym <- genCCallbackPrototype name' cb' name' Nothing       dynamic <- genDynamicCallableWrapper n typeSynonym cb       export (NamedSubsection SignalSection name') dynamic-      genCallbackWrapperFactory name' name'+      genCallbackWrapperFactory name' name' False       deprecatedPragma name' (callableDeprecated cb')-      genHaskellCallbackPrototype name' cb' name' WithoutClosures cbDoc+      genHaskellCallbackPrototype name' cb' name' WithoutClosures False cbDoc       when (callableHasClosures cb') $ do-           genHaskellCallbackPrototype name' cb' name' WithClosures cbDoc+           genHaskellCallbackPrototype name' cb' name' WithClosures False cbDoc            genDropClosures name' cb' name'       if callableThrows cb'       then do@@ -379,14 +396,19 @@         line $ "-- No Haskell->C wrapper generated since the function throws."         blank       else do-        genClosure name' cb' name' name' False-        genCallbackWrapper name' cb' name' False+        genClosure name' cb' name' name'+        genCallbackWrapper name' cb' name' Nothing  -- | Generate the given signal instance for the given API object. genSignalInfoInstance :: Name -> Signal -> CodeGen e () genSignalInfoInstance owner signal = group $ do+  api <- findAPIByName owner   let name = upperName owner-  let sn = (ucFirst . signalHaskellName . sigName) signal+      sn = (ucFirst . signalHaskellName . sigName) signal+      lcSignal = lcFirst sn+      qualifiedSignalName = dotModulePath (moduleLocation owner api)+                            <> "::" <> sigName signal+  hackageLink <- hackageModuleLink owner   si <- signalInfoName owner signal   bline $ "data " <> si   line $ "instance SignalInfo " <> si <> " where"@@ -395,8 +417,14 @@           cbHaskellType = signalConnectorName <> "Callback"       line $ "type HaskellCallbackType " <> si <> " = " <> cbHaskellType       line $ "connectSignal obj cb connectMode detail = do"-      indent $ genSignalConnector signal cbHaskellType "connectMode" "detail"-  export (NamedSubsection SignalSection $ lcFirst sn) si+      indent $ do+        genSignalConnector signal cbHaskellType "connectMode" "detail" "cb"+      line $ "dbgSignalInfo = P.Just (O.ResolvedSymbolInfo {"+      indent $ do+        line $ "O.resolvedSymbolName = \"" <> qualifiedSignalName <> "\""+        line $ ", O.resolvedSymbolURL = \"" <> hackageLink <> "#"+          <> haddockSignalAnchor <> lcSignal <> "\"})"+  export (NamedSubsection SignalSection $ lcSignal) si  -- | Write some simple debug message when signal generation fails, and -- generate a placeholder SignalInfo instance.@@ -436,19 +464,18 @@    deprecatedPragma cbType (callableDeprecated cb) -  genHaskellCallbackPrototype (lcFirst sn') cb cbType WithoutClosures (sigDoc s)+  genHaskellCallbackPrototype (lcFirst sn') cb cbType WithoutClosures True (sigDoc s) -  _ <- genCCallbackPrototype (lcFirst sn') cb cbType True+  _ <- genCCallbackPrototype (lcFirst sn') cb cbType (Just on') -  genCallbackWrapperFactory (lcFirst sn') cbType+  genCallbackWrapperFactory (lcFirst sn') cbType True    if callableThrows cb     then do       line $ "-- No Haskell->C wrapper generated since the function throws."       blank     else do-      genClosure (lcFirst sn') cb cbType signalConnectorName True-      genCallbackWrapper (lcFirst sn') cb cbType True+      genCallbackWrapper (lcFirst sn') cb cbType (Just on')    -- Wrapper for connecting functions to the signal   -- We can connect to a signal either before the default handler runs@@ -459,10 +486,15 @@     -- since if something provides signals it is necessarily a     -- GObject.     klass <- classConstraint on++    addLanguagePragma "ImplicitParams"+    addLanguagePragma "RankNTypes"+     let signatureConstraints = "(" <> klass <> " a, MonadIO m) =>"+        implicitSelfCBType = "((?self :: a) => " <> cbType <> ")"         signatureArgs = if sigDetailed s-          then "a -> P.Maybe T.Text -> " <> cbType <> " -> m SignalHandlerId"-          else "a -> " <> cbType <> " -> m SignalHandlerId"+          then "a -> P.Maybe T.Text -> " <> implicitSelfCBType <> " -> m SignalHandlerId"+          else "a -> " <> implicitSelfCBType <> " -> m SignalHandlerId"         signature = " :: " <> signatureConstraints <> " " <> signatureArgs         onName = "on" <> signalConnectorName         afterName = "after" <> signalConnectorName@@ -473,10 +505,14 @@       if sigDetailed s         then do         line $ onName <> " obj detail cb = liftIO $ do"-        indent $ genSignalConnector s cbType "SignalConnectBefore" "detail"+        indent $ do+          line $ "let wrapped self = let ?self = self in cb"+          genSignalConnector s cbType "SignalConnectBefore" "detail" "wrapped"         else do         line $ onName <> " obj cb = liftIO $ do"-        indent $ genSignalConnector s cbType "SignalConnectBefore" "Nothing"+        indent $ do+          line $ "let wrapped self = let ?self = self in cb"+          genSignalConnector s cbType "SignalConnectBefore" "Nothing" "wrapped"       export docSection onName      group $ do@@ -485,10 +521,14 @@       if sigDetailed s         then do         line $ afterName <> " obj detail cb = liftIO $ do"-        indent $ genSignalConnector s cbType "SignalConnectAfter" "detail"+        indent $ do+          line $ "let wrapped self = let ?self = self in cb"+          genSignalConnector s cbType "SignalConnectAfter" "detail" "wrapped"         else do         line $ afterName <> " obj cb = liftIO $ do"-        indent $ genSignalConnector s cbType "SignalConnectAfter" "Nothing"+        indent $ do+          line $ "let wrapped self = let ?self = self in cb"+          genSignalConnector s cbType "SignalConnectAfter" "Nothing" "wrapped"       export docSection afterName    cppIf CPPOverloading (genSignalInfoInstance on s)@@ -520,7 +560,9 @@         <> hsn <> " callback"       , "@"       , ""-      , detailedDoc ]+      , detailedDoc+      , ""+      , selfDoc]      detailedDoc :: Text     detailedDoc = if not (sigDetailed s)@@ -531,6 +573,12 @@         <> "::detail@” instead."       ] +    selfDoc :: Text+    selfDoc = T.unlines [+      "By default the object invoking the signal is not passed to the callback."+      , "If you need to access it, you can use the implit @?self@ parameter."+      , "Note that this requires activating the @ImplicitParams@ GHC extension."+      ]  -- | Generate the code for connecting the given signal. This assumes -- that it lives inside a @do@ block.@@ -538,9 +586,11 @@                    -> Text -- ^ Callback type                    -> Text -- ^ SignalConnectBefore or SignalConnectAfter                    -> Text -- ^ Detail+                   -> Text -- ^ Name of variable holding the callback                    -> CodeGen e ()-genSignalConnector (Signal {sigName = sn, sigCallable = cb}) cbType when detail = do-  cb' <- genWrappedCallback cb "cb" cbType True+genSignalConnector (Signal {sigName = sn, sigCallable = cb})+                   cbType when detail cbName = do+  cb' <- genWrappedCallback cb cbName cbType True   let cb'' = prime cb'   line $ cb'' <> " <- " <> callbackWrapperAllocator cbType <> " " <> cb'   line $ "connectSignalFunPtr obj \"" <> sn <> "\" " <> cb'' <> " " <> when
lib/Data/GI/CodeGen/Struct.hs view
@@ -26,11 +26,14 @@ import Data.GI.CodeGen.Code import Data.GI.CodeGen.Haddock (addSectionDocumentation, writeHaddock,                                 RelativeDocPosition(DocBeforeSymbol))+import Data.GI.CodeGen.ModulePath (dotModulePath) import Data.GI.CodeGen.SymbolNaming (upperName, lowerName,                                      underscoresToCamelCase,                                      qualifiedSymbol,                                      callbackHaskellToForeign,-                                     callbackWrapperAllocator)+                                     callbackWrapperAllocator,+                                     haddockAttrAnchor, moduleLocation,+                                     hackageModuleLink)  import Data.GI.CodeGen.Type import Data.GI.CodeGen.Util@@ -334,6 +337,12 @@   transferType <- fieldTransferType (fieldType field)   transferConstraint <- fieldTransferTypeConstraint (fieldType field) +  api <- findAPIByName owner+  hackageLink <- hackageModuleLink owner+  let qualifiedAttrName = dotModulePath (moduleLocation owner api)+                          <> "." <> labelName field+      attrInfoURL = hackageLink <> "#" <> haddockAttrAnchor <> labelName field+   line $ "data " <> it   line $ "instance AttrInfo " <> it <> " where"   indent $ do@@ -366,6 +375,11 @@           line $ "attrTransfer _ v = do"           indent $ genFieldTransfer "v" (fieldType field)       else line $ "attrTransfer = undefined"+    line $ "dbgAttrInfo = P.Just (O.ResolvedSymbolInfo {"+    indent $ do+      line $ "O.resolvedSymbolName = \"" <> qualifiedAttrName <> "\""+      line $ ", O.resolvedSymbolURL = \"" <> attrInfoURL <> "\""+      line $ "})"    blank 
lib/Data/GI/CodeGen/SymbolNaming.hs view
@@ -31,6 +31,8 @@     , normalizedAPIName      , hackageModuleLink+    , haddockSignalAnchor+    , haddockAttrAnchor     ) where  #if !MIN_VERSION_base(4,11,0)@@ -268,9 +270,11 @@  -- | Return the name for the signal in Haskell CamelCase conventions. signalHaskellName :: Text -> Text-signalHaskellName sn = let (w:ws) = T.split (== '-') sn-                       in w <> T.concat (map ucFirst ws)-+signalHaskellName sn = case T.split (== '-') sn of+                         [] -> ""  -- Won't happen due to the+                                   -- definition of T.split, but GHC+                                   -- does not know this.+                         w:ws -> w <> T.concat (map ucFirst ws)  -- | Return a link to the hackage package for the given name. Note -- that the generated link will only be valid if the name belongs to@@ -284,3 +288,10 @@   return $ "https://hackage.haskell.org/package/" <> pkg <> "/docs/"            <> location <> ".html" +-- | Prefix in Haddock for the signal anchor.+haddockSignalAnchor :: Text+haddockSignalAnchor = "g:signal:"++-- | Prefix in Haddock for the attribute anchor.+haddockAttrAnchor :: Text+haddockAttrAnchor = "g:attr:"
lib/Data/GI/GIR/Type.hs view
@@ -94,6 +94,7 @@ -- | A hash table. parseHashTable :: Parser Type parseHashTable = parseTypeElements >>= \case+                 [] -> return $ TGHash (TBasicType TPtr) (TBasicType TPtr)                  [Just key, Just value] -> return $ TGHash key value                  other -> parseError $ "Unsupported hash type: "                                        <> T.pack (show other)