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 +4/−0
- haskell-gi.cabal +1/−1
- lib/Data/GI/CodeGen/Callable.hs +5/−2
- lib/Data/GI/CodeGen/CodeGen.hs +5/−1
- lib/Data/GI/CodeGen/Fixups.hs +60/−1
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.