packages feed

haskell-gi 0.26.5 → 0.26.6

raw patch · 5 files changed

+75/−5 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.GI.CodeGen.Fixups: fixClosures :: (Name, API) -> (Name, API)

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+### 0.26.6+++ Work around changing conventions about what the `closure n` annotation means: many annotations appear on the callback, pointing to the user_data argument, but sometimes it also appears on the user_data argument, pointing to the callback. See [issue 407](https://github.com/haskell-gi/haskell-gi/issues/407) for a place where this becomes a problem.+ ### 0.26.5  + Add a reference to ?self argument in signals. See [issue 408](https://github.com/haskell-gi/haskell-gi/issues/408) for the motivation.
haskell-gi.cabal view
@@ -1,5 +1,5 @@ name:                haskell-gi-version:             0.26.5+version:             0.26.6 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.
lib/Data/GI/CodeGen/Callable.hs view
@@ -584,8 +584,11 @@                   Nothing -> badIntroError $ "Could not find " <> name                                 <> " in " <> T.pack (ppShow callable) <> "\n"                                 <> T.pack (ppShow nameMap)-       when (argScope arg == ScopeTypeCall) $-            line $ "safeFreeFunPtr $ castFunPtrToPtr " <> name'+       when (argScope arg == ScopeTypeCall) $ do+         isCallback <- typeIsCallback (argType arg)+         if isCallback+           then line $ "safeFreeFunPtr $ castFunPtrToPtr " <> name'+           else comment $ "XXX: Ignoring scope annotation on a non-callback argument: " <> name  -- | Format the signature of the Haskell binding for the `Callable`. formatHSignature :: Callable -> ForeignSymbol -> ExposeClosures -> ExcCodeGen ()
lib/Data/GI/CodeGen/CodeGen.hs view
@@ -21,7 +21,8 @@ import Data.GI.CodeGen.EnumFlags (genEnum, genFlags) import Data.GI.CodeGen.Fixups (dropMovedItems, guessPropertyNullability,                                detectGObject, dropDuplicatedFields,-                               checkClosureDestructors, fixSymbolNaming)+                               checkClosureDestructors, fixSymbolNaming,+                               fixClosures) import Data.GI.CodeGen.GObject import Data.GI.CodeGen.Haddock (deprecatedPragma, addSectionDocumentation,                                 writeHaddock,@@ -553,6 +554,9 @@       -- destructor for a user_data argument has an associated       -- user_data argument.       $ map checkClosureDestructors+      -- Make sure that the argClosure argument refers to a callback,+      -- not to the user_data field.+      $ map fixClosures       -- Make sure that the symbols to be generated are valid       -- Haskell identifiers, when necessary.       $ map fixSymbolNaming
lib/Data/GI/CodeGen/Fixups.hs view
@@ -5,17 +5,20 @@     , detectGObject     , dropDuplicatedFields     , checkClosureDestructors+    , fixClosures     , fixSymbolNaming     ) where  import Data.Char (generalCategory, GeneralCategory(UppercaseLetter)) import Data.Maybe (isNothing, isJust)+import qualified Data.Map as M #if !MIN_VERSION_base(4,13,0) import Data.Monoid ((<>)) #endif import qualified Data.Set as S import qualified Data.Text as T +import Data.GI.CodeGen.Type import Data.GI.CodeGen.API  -- | Remove functions and methods annotated with "moved-to".@@ -178,7 +181,7 @@         checkMethod m = m {methodCallable =                              checkCallableDestructors (methodCallable m)} --- | If any argument for the callable has a associated destroyer for+-- | If any argument for the callable has an associated destroyer for -- the user_data, but no associated user_data, drop the destroyer -- annotation. checkCallableDestructors :: Callable -> Callable@@ -187,6 +190,62 @@         checkArg arg = if argDestroy arg >= 0 && argClosure arg == -1                        then arg {argDestroy = -1}                        else arg++-- | Sometimes it is the callback that is annotated with the (closure+-- user_data) annotation, and sometimes the user_data parameter+-- itself, with (closure callback) pointing to the callback. The+-- following code makes sure that the annotation is on the callable+-- only. Note that this goes against the official gobject+-- introspection spec, but there is more code using this convention+-- than otherwise, and the gir generator seems to add closure+-- annotations in both directions when using the new convention+-- anyway.+fixCallableClosures :: Callable -> Callable+fixCallableClosures c = c {args = map fixupArg (zip [0..] (args c))}+  where fixupArg :: (Int, Arg) -> Arg+        fixupArg (n, arg) = if isUserData arg+                            then arg {argClosure = -1}+                            else+                              case M.lookup n reverseMap of+                                Just user_data -> arg {argClosure = user_data}+                                Nothing -> arg++        -- Map from callbacks to their corresponding user_data+        -- arguments, obtained by looking to the argClosure value for+        -- the user_data argument.+        reverseMap :: M.Map Int Int+        reverseMap = M.fromList+          . map (\(n, arg) -> (argClosure arg, n))+          . filter (isUserData . snd)+          . filter ((/= -1) . argClosure . snd)+          $ zip [0..] (args c)++        isUserData :: Arg -> Bool+        isUserData arg = argScope arg == ScopeTypeInvalid ||+                         argType arg == TBasicType TPtr++-- | Closures are often incorrectly assigned, with the closure+-- annotation on the callback, instead of in the closure (user_data)+-- parameter itself. The following makes sure that things are as they+-- should.+fixClosures :: (Name, API) -> (Name, API)+fixClosures (n, APIObject o) =+  (n, APIObject (o {objMethods = fixMethodClosures (objMethods o)}))+fixClosures (n, APIInterface i) =+  (n, APIInterface (i {ifMethods = fixMethodClosures (ifMethods i)}))+fixClosures (n, APIStruct s) =+  (n, APIStruct (s {structMethods = fixMethodClosures (structMethods s)}))+fixClosures (n, APIUnion u) =+  (n, APIUnion (u {unionMethods = fixMethodClosures (unionMethods u)}))+fixClosures (n, APIFunction f) =+  (n, APIFunction (f {fnCallable = fixCallableClosures (fnCallable f)}))+fixClosures (n, api) = (n, api)++fixMethodClosures :: [Method] -> [Method]+fixMethodClosures = map fixMethod+  where fixMethod :: Method -> Method+        fixMethod m = m {methodCallable =+                            fixCallableClosures (methodCallable m)}  -- | Some symbols have names that are not valid Haskell identifiers, -- fix that here.