packages feed

haskell-gi 0.21.5 → 0.22.0

raw patch · 18 files changed

+318/−130 lines, 18 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.CabalHooks: configureDryRun :: Text -> Text -> Maybe FilePath -> IO [Text]
+ Data.GI.CodeGen.Code: getFreshTypeVariable :: CodeGen Text
+ Data.GI.CodeGen.Code: resetTypeVariableScope :: CodeGen ()
+ Data.GI.CodeGen.Conversions: haskellTypeConstraint :: Type -> CodeGen Text
+ Data.GI.CodeGen.Conversions: inboundHaskellType :: Type -> CodeGen TypeRep
+ Data.GI.CodeGen.Fixups: dropDuplicatedFields :: (Name, API) -> (Name, API)
+ Data.GI.CodeGen.Type: TGClosure :: Maybe Type -> Type
+ Data.GI.GIR.BasicTypes: TGClosure :: Maybe Type -> Type
- Data.GI.CodeGen.Conversions: argumentType :: [Char] -> Type -> CodeGen ([Char], Text, [Text])
+ Data.GI.CodeGen.Conversions: argumentType :: Type -> CodeGen (Text, [Text])
- Data.GI.CodeGen.ProjectInfo: licenseText :: Text
+ Data.GI.CodeGen.ProjectInfo: licenseText :: Text -> Text

Files

LICENSE view
@@ -1,3 +1,17 @@+The haskell-gi library and included works are provided under the terms of the+GNU Library General Public License (LGPL) version 2.1 with the following+exception:++Static linking of applications or any other source to the haskell-gi library+does not constitute a modified or derivative work and does not require the+author(s) to provide source code for said work, to link against the shared+haskell-gi libraries, or to link their applications against a user-supplied+version of haskell-gi. If you link applications to a modified version of+haskell-gi, then the changes to haskell-gi must be provided under the terms of+the LGPL.++----------------------------------------------------------------------------+                   GNU LESSER GENERAL PUBLIC LICENSE                        Version 2.1, February 1999 
haskell-gi.cabal view
@@ -1,5 +1,5 @@ name:                haskell-gi-version:             0.21.5+version:             0.22.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.@@ -10,7 +10,7 @@ author:              Will Thompson,                      Iñaki García Etxebarria,                      Jonas Platte-maintainer:          Iñaki García Etxebarria (garetxe@gmail.com)+maintainer:          Iñaki García Etxebarria (inaki@blueleaf.cc) stability:           Experimental category:            Development build-type:          Simple@@ -25,8 +25,8 @@  Library   pkgconfig-depends:   gobject-introspection-1.0 >= 1.32, gobject-2.0 >= 2.32-  build-depends:       base >= 4.7 && < 5,-                       haskell-gi-base == 0.21.*,+  build-depends:       base >= 4.9 && < 5,+                       haskell-gi-base == 0.22.*,                        Cabal >= 1.24,                        attoparsec == 0.13.*,                        containers,@@ -43,14 +43,12 @@                        regex-tdfa >= 1.2,                        text >= 1.0 -  if !impl(ghc >= 8.0)-    build-depends: semigroups == 0.18.*+  build-depends: semigroups == 0.18.*    extensions:          CPP, ForeignFunctionInterface, DoAndIfThenElse, LambdaCase, RankNTypes, OverloadedStrings   ghc-options:         -Wall -fwarn-incomplete-patterns -fno-warn-name-shadowing -  if impl(ghc >= 8.0)-     ghc-options: -Wcompat+  ghc-options: -Wcompat    c-sources:           lib/c/enumStorage.c 
lib/Data/GI/CodeGen/CabalHooks.hs view
@@ -2,6 +2,7 @@ -- bindings. module Data.GI.CodeGen.CabalHooks     ( setupHaskellGIBinding+    , configureDryRun     ) where  import qualified Distribution.ModuleName as MN@@ -12,7 +13,8 @@ import Distribution.PackageDescription  import Data.GI.CodeGen.API (loadGIRInfo)-import Data.GI.CodeGen.Code (genCode, writeModuleTree, listModuleTree)+import Data.GI.CodeGen.Code (genCode, writeModuleTree, listModuleTree,+                             ModuleInfo) import Data.GI.CodeGen.CodeGen (genModule) import Data.GI.CodeGen.Config (Config(..)) import Data.GI.CodeGen.LibGIRepository (setupTypelibSearchPath)@@ -34,17 +36,13 @@ type ConfHook = (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags               -> IO LocalBuildInfo --- | A convenience helper for `confHook`, such that bindings for the--- given module are generated in the @configure@ step of @cabal@.-confCodeGenHook :: Text -- ^ name-                -> Text -- ^ version-                -> Bool -- ^ verbose-                -> Maybe FilePath -- ^ overrides file-                -> Maybe FilePath -- ^ output dir-                -> ConfHook -- ^ previous `confHook`-                -> ConfHook-confCodeGenHook name version verbosity overrides outputDir-                defaultConfHook (gpd, hbi) flags = do+-- | Generate the code for the given module.+genModuleCode :: Text -- ^ name+              -> Text -- ^ version+              -> Bool -- ^ verbose+              -> Maybe FilePath -- ^ overrides file+              -> IO ModuleInfo+genModuleCode name version verbosity overrides = do   setupTypelibSearchPath []    ovs <- case overrides of@@ -61,8 +59,21 @@                     verbose = verbosity,                     overrides = ovs} -  let m = genCode cfg allAPIs (toModulePath name) (genModule apis)+  return $ genCode cfg allAPIs (toModulePath name) (genModule apis) +-- | A convenience helper for `confHook`, such that bindings for the+-- given module are generated in the @configure@ step of @cabal@.+confCodeGenHook :: Text -- ^ name+                -> Text -- ^ version+                -> Bool -- ^ verbose+                -> Maybe FilePath -- ^ overrides file+                -> Maybe FilePath -- ^ output dir+                -> ConfHook -- ^ previous `confHook`+                -> ConfHook+confCodeGenHook name version verbosity overrides outputDir+                defaultConfHook (gpd, hbi) flags = do+  m <- genModuleCode name version verbosity overrides+   let em' = map (MN.fromString . T.unpack) (listModuleTree m)       ctd' = ((condTreeData . fromJust . condLibrary) gpd) {exposedModules = em'}       cL' = ((fromJust . condLibrary) gpd) {condTreeData = ctd'}@@ -90,3 +101,13 @@                                        overridesFile outputDir                                        (confHook simpleUserHooks)                           })++-- | Return the list of modules that `setupHaskellGIBinding` would create.+configureDryRun :: Text -- ^ name+                -> Text -- ^ version+                -> Maybe FilePath+                -> IO [Text]+configureDryRun name version overrides = do+  m <- genModuleCode name version False overrides++  return (listModuleTree m)
lib/Data/GI/CodeGen/Callable.hs view
@@ -25,7 +25,7 @@ #endif import Control.Monad (forM, forM_, when, void) import Data.Bool (bool)-import Data.List (nub, (\\))+import Data.List (nub) import Data.Maybe (isJust) import Data.Monoid ((<>)) import Data.Tuple (swap)@@ -123,16 +123,16 @@ -- Given the list of arguments returns the list of constraints and the -- list of types in the signature. inArgInterfaces :: [Arg] -> ExcCodeGen ([Text], [Text])-inArgInterfaces inArgs = consAndTypes (['a'..'z'] \\ ['m']) inArgs-  where-    consAndTypes :: [Char] -> [Arg] -> ExcCodeGen ([Text], [Text])-    consAndTypes _ [] = return ([], [])-    consAndTypes letters (arg:args) = do-      (ls, t, cons) <- argumentType letters $ argType arg-      t' <- wrapMaybe arg >>= bool (return t)-                                   (return $ "Maybe (" <> t <> ")")-      (restCons, restTypes) <- consAndTypes ls args-      return (cons <> restCons, t' : restTypes)+inArgInterfaces args = do+  resetTypeVariableScope+  go args+  where go [] = return ([], [])+        go (arg:args) = do+          (t, cons) <- argumentType (argType arg)+          t' <- wrapMaybe arg >>= bool (return t)+            (return $ "Maybe (" <> t <> ")")+          (restCons, restTypes) <- go args+          return (cons <> restCons, t' : restTypes)  -- Given a callable, return a list of (array, length) pairs, where in -- each pair "length" is the argument holding the length of the
lib/Data/GI/CodeGen/Code.hs view
@@ -44,6 +44,9 @@     , setModuleFlags     , setModuleMinBase +    , getFreshTypeVariable+    , resetTypeVariableScope+     , exportModule     , exportDecl     , export@@ -233,13 +236,21 @@ data CGState = CGState {   cgsCPPConditionals :: [CPPConditional] -- ^ Active CPP conditionals,                                          -- outermost condition first.+  , cgsNextAvailableTyvar :: NamedTyvar -- ^ Next unused type+                                        -- variable.   } +-- | The name for a type variable.+data NamedTyvar = SingleCharTyvar Char+                -- ^ A single variable type variable: 'a', 'b', etc...+                | IndexedTyvar Text Integer+                -- ^ An indexed type variable: 'a17', 'key1', ...+ -- | Clean slate for `CGState`. emptyCGState :: CGState-emptyCGState = CGState {-  cgsCPPConditionals = []-  }+emptyCGState = CGState { cgsCPPConditionals = []+                       , cgsNextAvailableTyvar = SingleCharTyvar 'a'+                       }  -- | The base type for the code generator monad. type BaseCodeGen excType a =@@ -497,6 +508,28 @@ missingInfoError :: Text -> ExcCodeGen a missingInfoError s = throwError $ CGErrorMissingInfo s +-- | Get a type variable unused in the current scope.+getFreshTypeVariable :: CodeGen Text+getFreshTypeVariable = do+  (cgs@(CGState{cgsNextAvailableTyvar = available}), s) <- get+  let (tyvar, next) =+        case available of+          SingleCharTyvar char -> case char of+            'z' -> ("z", IndexedTyvar "a" 0)+            -- 'm' is reserved for the MonadIO constraint in signatures+            'm' -> ("n", SingleCharTyvar 'o')+            c -> (T.singleton c, SingleCharTyvar (toEnum $ fromEnum c + 1))+          IndexedTyvar root index -> (root <> tshow index,+                                      IndexedTyvar root (index+1))+  put (cgs {cgsNextAvailableTyvar = next}, s)+  return tyvar++-- | Introduce a new scope for type variable naming: the next fresh+-- variable will be called 'a'.+resetTypeVariableScope :: CodeGen ()+resetTypeVariableScope =+  modify' (\(cgs, s) -> (cgs {cgsNextAvailableTyvar = SingleCharTyvar 'a'}, s))+ findAPI :: Type -> CodeGen (Maybe API) findAPI TError = Just <$> findAPIByName (Name "GLib" "Error") findAPI (TInterface n) = Just <$> findAPIByName n@@ -563,8 +596,8 @@   blank   return x     where addConditional :: CGState -> CGState-          addConditional cgs = CGState {cgsCPPConditionals = CPPIf cond :-                                         cgsCPPConditionals cgs}+          addConditional cgs = cgs {cgsCPPConditionals = CPPIf cond :+                                                         cgsCPPConditionals cgs}  -- | Possible features to test via CPP. data CPPGuard = CPPOverloading -- ^ Enable overloading@@ -853,15 +886,18 @@                 , ""                 , "import qualified Data.GI.Base.Attributes as GI.Attributes"                 , "import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr"+                , "import qualified Data.GI.Base.GClosure as B.GClosure"                 , "import qualified Data.GI.Base.GError as B.GError"                 , "import qualified Data.GI.Base.GVariant as B.GVariant"                 , "import qualified Data.GI.Base.GValue as B.GValue"                 , "import qualified Data.GI.Base.GParamSpec as B.GParamSpec"                 , "import qualified Data.GI.Base.CallStack as B.CallStack"+                , "import qualified Data.GI.Base.Properties as B.Properties"                 , "import qualified Data.Text as T"                 , "import qualified Data.ByteString.Char8 as B"                 , "import qualified Data.Map as Map"-                , "import qualified Foreign.Ptr as FP" ]+                , "import qualified Foreign.Ptr as FP"+                , "import qualified GHC.OverloadedLabels as OL" ]  -- | Like `dotModulePath`, but add a "GI." prefix. dotWithPrefix :: ModulePath -> Text
lib/Data/GI/CodeGen/CodeGen.hs view
@@ -22,7 +22,7 @@ import Data.GI.CodeGen.Code import Data.GI.CodeGen.EnumFlags (genEnum, genFlags) import Data.GI.CodeGen.Fixups (dropMovedItems, guessPropertyNullability,-                               detectGObject)+                               detectGObject, dropDuplicatedFields) import Data.GI.CodeGen.GObject import Data.GI.CodeGen.Haddock (deprecatedPragma, addSectionDocumentation,                                 writeHaddock,@@ -39,7 +39,7 @@                   fixAPIStructs, ignoreStruct, genZeroStruct, genZeroUnion,                   genWrappedPtr) import Data.GI.CodeGen.SymbolNaming (upperName, classConstraint, noName,-                                     submoduleLocation, lowerName)+                                     submoduleLocation, lowerName, qualifiedAPI) import Data.GI.CodeGen.Type import Data.GI.CodeGen.Util (tshow) @@ -246,24 +246,31 @@   group $ do     bline $ "instance GObject " <> name' <> " where"     indent $ group $ do-            line $ "gobjectType _ = c_" <> cn_+            line $ "gobjectType = c_" <> cn_    className <- classConstraint n   group $ do     exportDecl className     writeHaddock DocBeforeSymbol (classDoc name') -    bline $ "class GObject o => " <> className <> " o"-    line $ "#if MIN_VERSION_base(4,9,0)"-    line $ "instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError "-             <> name' <> " a) =>"-    line $ "    " <> className <> " a"-    line $ "#endif"-    bline $ "instance " <> className <> " " <> name'-    forM_ parents $ \parent -> do-        pcls <- classConstraint parent-        line $ "instance " <> pcls <> " " <> name'+    -- Create the IsX constraint. We cannot simply say+    --+    -- > type IsX o = (GObject o, ...)+    --+    -- since we sometimes need to refer to @IsX@ itself, without+    -- applying it. We instead use the trick of creating a class with+    -- a universal instance.+    let constraints = "(GObject o, O.IsDescendantOf " <> name' <> " o)"+    bline $ "class " <> constraints <> " => " <> className <> " o"+    bline $ "instance " <> constraints <> " => " <> className <> " o" +    blank++    qualifiedParents <- mapM qualifiedAPI parents+    bline $ "instance O.HasParentTypes " <> name'+    line $ "type instance O.ParentTypes " <> name' <> " = '["+      <> T.intercalate ", " qualifiedParents <> "]"+   -- Safe downcasting.   group $ do     let safeCast = "to" <> name'@@ -449,6 +456,9 @@             -- Not every interface providing signals or properties is             -- correctly annotated as descending from GObject, fix this.           $ map detectGObject+            -- Some APIs contain duplicated fields by mistake, drop+            -- the duplicates.+          $ map dropDuplicatedFields           $ M.toList           $ apis 
lib/Data/GI/CodeGen/Conversions.hs view
@@ -13,6 +13,8 @@     , transientToH     , haskellType     , isoHaskellType+    , inboundHaskellType+    , haskellTypeConstraint     , foreignType      , argumentType@@ -212,6 +214,21 @@   then return $ M "B.GParamSpec.disownGParamSpec"   else return $ M "unsafeManagedPtrGetPtr" +hClosureToF :: Transfer -> Maybe Type -> CodeGen Constructor+-- Untyped closures+hClosureToF transfer Nothing =+  if transfer == TransferEverything+  then return $ M "B.GClosure.disownGClosure"+  -- We cast the point here because the foreign type for untyped+  -- closures is always represented as Ptr (GClosure ()), while the+  -- corresponding Haskell type is the parametric "GClosure a".+  else return $ M "unsafeManagedPtrCastPtr"+-- Typed closures+hClosureToF transfer (Just _) =+  if transfer == TransferEverything+  then return $ M "B.GClosure.disownGClosure"+  else return $ M "unsafeManagedPtrGetPtr"+ hBoxedToF :: Transfer -> CodeGen Constructor hBoxedToF transfer =   if transfer == TransferEverything@@ -245,6 +262,7 @@     | TError <- t = hBoxedToF transfer     | TVariant <- t = hVariantToF transfer     | TParamSpec <- t = hParamSpecToF transfer+    | TGClosure c <- t = hClosureToF transfer c     | Just (APIEnum _) <- a = return "(fromIntegral . fromEnum)"     | Just (APIFlags _) <- a = return "gflagsToWord"     | Just (APIObject _) <- a = hObjectToF t transfer@@ -460,6 +478,19 @@                   TransferEverything -> "B.GParamSpec.wrapGParamSpecPtr"                   _ -> "B.GParamSpec.newGParamSpecFromPtr" +fClosureToH :: Transfer -> Maybe Type -> CodeGen Constructor+-- Untyped closures+fClosureToH transfer Nothing =+  return $ M $ case transfer of+                  TransferEverything ->+                    parenthesize $ "B.GClosure.wrapGClosurePtr . FP.castPtr"+                  _ -> parenthesize $ "B.GClosure.newGClosureFromPtr . FP.castPtr"+-- Typed closures+fClosureToH transfer (Just _) =+  return $ M $ case transfer of+                  TransferEverything -> "B.GClosure.wrapGClosurePtr"+                  _ -> "B.GClosure.newGClosureFromPtr"+ fToH' :: Type -> Maybe API -> TypeRep -> TypeRep -> Transfer          -> ExcCodeGen Constructor fToH' t a hType fType transfer@@ -469,6 +500,7 @@     | TError <- t = boxedForeignPtr "GError" transfer     | TVariant <- t = fVariantToH transfer     | TParamSpec <- t = fParamSpecToH transfer+    | TGClosure c <- t = fClosureToH transfer c     | Just (APIStruct s) <- a = structForeignPtr s hType transfer     | Just (APIUnion u) <- a = unionForeignPtr u hType transfer     | Just (APIObject _) <- a = fObjectToH t hType transfer@@ -665,15 +697,14 @@ -- | Given a type find the typeclasses the type belongs to, and return -- the representation of the type in the function signature and the -- list of typeclass constraints for the type.-argumentType :: [Char] -> Type -> CodeGen ([Char], Text, [Text])-argumentType [] _               = error "out of letters"-argumentType letters (TGList a) = do-  (ls, name, constraints) <- argumentType letters a-  return (ls, "[" <> name <> "]", constraints)-argumentType letters (TGSList a) = do-  (ls, name, constraints) <- argumentType letters a-  return (ls, "[" <> name <> "]", constraints)-argumentType letters@(l:ls) t = do+argumentType :: Type -> CodeGen (Text, [Text])+argumentType (TGList a) = do+  (name, constraints) <- argumentType a+  return ("[" <> name <> "]", constraints)+argumentType (TGSList a) = do+  (name, constraints) <- argumentType a+  return ("[" <> name <> "]", constraints)+argumentType t = do   api <- findAPI t   s <- typeShow <$> haskellType t   case api of@@ -681,22 +712,24 @@     -- we allow for any object descending from it.     Just (APIInterface _) -> do       cls <- typeConstraint t-      return (ls, T.singleton l, [cls <> " " <> T.singleton l])+      l <- getFreshTypeVariable+      return (l, [cls <> " " <> l])     Just (APIObject _) -> do       isGO <- isGObject t       if isGO         then do cls <- typeConstraint t-                return (ls, T.singleton l, [cls <> " " <> T.singleton l])-        else return (letters, s, [])+                l <- getFreshTypeVariable+                return (l, [cls <> " " <> l])+        else return (s, [])     Just (APICallback cb) ->       -- See [Note: Callables that throw]       if callableThrows (cbCallable cb)       then do         ft <- typeShow <$> foreignType t-        return (letters, ft, [])+        return (ft, [])       else-        return (letters, s, [])-    _ -> return (letters, s, [])+        return (s, [])+    _ -> return (s, [])  haskellBasicType :: BasicType -> TypeRep haskellBasicType TPtr      = ptr $ con0 "()"@@ -763,7 +796,18 @@ haskellType TError = return $ "GError" `con` [] haskellType TVariant = return $ "GVariant" `con` [] haskellType TParamSpec = return $ "GParamSpec" `con` []-haskellType (TInterface (Name "GObject" "Closure")) = return $ "Closure" `con` []+haskellType (TGClosure (Just inner@(TInterface n))) = do+  innerAPI <- getAPI inner+  case innerAPI of+    APICallback _ -> do+      tname <- qualifiedSymbol (callbackCType $ name n) n+      return $ "GClosure" `con` [con0 tname]+    -- The given inner type does not make sense, so we treat it as an+    -- untyped closure.+    _ -> haskellType (TGClosure Nothing)+haskellType (TGClosure _) = do+  tyvar <- getFreshTypeVariable+  return $ "GClosure" `con` [con0 tyvar] haskellType (TInterface (Name "GObject" "Value")) = return $ "GValue" `con` [] haskellType t@(TInterface n) = do   api <- getAPI t@@ -772,6 +816,36 @@              (APIFlags _) -> "[]" `con` [tname `con` []]              _ -> tname `con` [] +-- | For convenience untyped `TGClosure` types have a type variable on+-- the Haskell side when they are arguments to functions, but we do+-- not want this when they appear as arguments to callbacks/signals,+-- or return types of properties, as it would force the type+-- synonym/type family to depend on the type variable. Note that for+-- types which are not untyped `TGClosure` this is equivalent to+-- `isoHaskellType`.+inboundHaskellType :: Type -> CodeGen TypeRep+inboundHaskellType (TGClosure Nothing) =+  return $ "GClosure" `con` [con0 "()"]+inboundHaskellType t = isoHaskellType t++-- | The constraint for setting the given type in properties.+haskellTypeConstraint :: Type -> CodeGen Text+haskellTypeConstraint (TGClosure Nothing) =+  return $ "(~) " <> parenthesize (typeShow ("GClosure" `con` [con0 "()"]))+haskellTypeConstraint t = do+  isGO <- isGObject t+  if isGO+    then typeConstraint t+    else do+      isCallback <- typeIsCallback t+      hInType <- if isCallback+                 then typeShow <$> foreignType t+                 else typeShow <$> haskellType t+      return $ "(~) " <> if T.any (== ' ') hInType+                         then parenthesize hInType+                         else hInType++ -- | Whether the callable has closure arguments (i.e. "user_data" -- style arguments). callableHasClosures :: Callable -> Bool@@ -847,8 +921,8 @@ foreignType t@TError = ptr <$> haskellType t foreignType t@TVariant = ptr <$> haskellType t foreignType t@TParamSpec = ptr <$> haskellType t-foreignType (TInterface (Name "GObject" "Closure")) =-    return $ ptr $ "Closure" `con` []+foreignType (TGClosure Nothing) = return $ ptr ("GClosure" `con` [con0 "()"])+foreignType t@(TGClosure (Just _)) = ptr <$> haskellType t foreignType (TInterface (Name "GObject" "Value")) =   return $ ptr $ "GValue" `con` [] foreignType t@(TInterface n) = do@@ -903,6 +977,7 @@ isManaged TError = return True isManaged TVariant = return True isManaged TParamSpec = return True+isManaged (TGClosure _) = return True isManaged t@(TInterface _) = do   a <- findAPI t   case a of
lib/Data/GI/CodeGen/Fixups.hs view
@@ -3,10 +3,12 @@     ( dropMovedItems     , guessPropertyNullability     , detectGObject+    , dropDuplicatedFields     ) where  import Data.Maybe (isNothing, isJust) import Data.Monoid ((<>))+import qualified Data.Set as S import qualified Data.Text as T  import Data.GI.CodeGen.API@@ -130,3 +132,21 @@                                         gobject : ifPrerequisites iface}))   else (n, APIInterface iface) detectGObject api = api++-- | Drop any fields whose name coincides with that of a previous+-- element. Note that this function keeps ordering.+dropDuplicatedEnumFields :: Enumeration -> Enumeration+dropDuplicatedEnumFields enum =+  enum{enumMembers = dropDuplicates S.empty (enumMembers enum)}+  where dropDuplicates :: S.Set T.Text -> [EnumerationMember] -> [EnumerationMember]+        dropDuplicates _        []     = []+        dropDuplicates previous (m:ms) =+          if enumMemberName m `S.member` previous+          then dropDuplicates previous ms+          else m : dropDuplicates (S.insert (enumMemberName m) previous) ms++-- | Some libraries include duplicated flags by mistake, drop those.+dropDuplicatedFields :: (Name, API) -> (Name, API)+dropDuplicatedFields (n, APIFlags (Flags enum)) =+  (n, APIFlags (Flags $ dropDuplicatedEnumFields enum))+dropDuplicatedFields (n, api) = (n, api)
lib/Data/GI/CodeGen/OverloadedMethods.hs view
@@ -28,19 +28,12 @@ genMethodResolver n = do   group $ do     line $ "instance (info ~ Resolve" <> n <> "Method t " <> n <> ", "-          <> "O.MethodInfo info " <> n <> " p) => O.IsLabelProxy t ("-          <> n <> " -> p) where"-    indent $ line $ "fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)"-  group $ do-    line $ "#if MIN_VERSION_base(4,9,0)"-    line $ "instance (info ~ Resolve" <> n <> "Method t " <> n <> ", "-          <> "O.MethodInfo info " <> n <> " p) => O.IsLabel t ("+          <> "O.MethodInfo info " <> n <> " p) => OL.IsLabel t ("           <> n <> " -> p) where"     line $ "#if MIN_VERSION_base(4,10,0)"     indent $ line $ "fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)"     line $ "#else"     indent $ line $ "fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)"-    line $ "#endif"     line $ "#endif"  -- | Generate the `MethodList` instance given the list of methods for
lib/Data/GI/CodeGen/OverloadedSignals.hs view
@@ -55,16 +55,10 @@   signalNames <- findSignalNames allAPIs   forM_ signalNames $ \sn -> group $ do     let camelName = hyphensToCamelCase sn-    line $ "#if MIN_VERSION_base(4,8,0)"     line $ "pattern " <> camelName <>              " :: SignalProxy object (ResolveSignal \""              <> lcFirst camelName <> "\" object)"     line $ "pattern " <> camelName <> " = SignalProxy"-    line $ "#else"-    line $ "pattern " <> camelName <> " = SignalProxy :: forall info object. "-             <> "info ~ ResolveSignal \"" <> lcFirst camelName-             <> "\" object => SignalProxy object info"-    line $ "#endif"     exportDecl $ "pattern " <> camelName  -- | Qualified name for the "(sigName, info)" tag for a given signal.
lib/Data/GI/CodeGen/ProjectInfo.hs view
@@ -14,6 +14,7 @@     , standardDeps     ) where +import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text as T (unlines) @@ -24,7 +25,7 @@ authors = "Will Thompson, Iñaki García Etxebarria and Jonas Platte"  maintainers :: Text-maintainers = "Iñaki García Etxebarria (garetxe@gmail.com)"+maintainers = "Iñaki García Etxebarria (inaki@blueleaf.cc)"  license :: Text license = "LGPL-2.1"@@ -36,7 +37,7 @@                      "OverloadedStrings", "NegativeLiterals", "ConstraintKinds",                      "TypeFamilies", "MultiParamTypeClasses", "KindSignatures",                      "FlexibleInstances", "UndecidableInstances", "DataKinds",-                     "FlexibleContexts"]+                     "FlexibleContexts", "UndecidableSuperClasses"]  -- | Extensions that will be used in some modules, but we do not wish -- to turn on by default.@@ -66,8 +67,25 @@ category :: Text category = "Bindings" -licenseText :: Text-licenseText = T.unlines+staticLinkingException :: Text -> Text+staticLinkingException name = T.unlines+ ["The " <> name <> " library and included works are provided under the terms of the"+ ,"GNU Library General Public License (LGPL) version 2.1 with the following"+ ,"exception:"+ ,""+ ,"Static linking of applications or any other source to the " <> name <> " library"+ ,"does not constitute a modified or derivative work and does not require"+ ,"the author(s) to provide source code for said work, to link against the"+ ,"shared " <> name <> " libraries, or to link their applications against a"+ ,"user-supplied version of " <> name <> ". If you link applications to a modified"+ ,"version of " <> name <> ", then the changes to " <> name <> " must be provided under the"+ ,"terms of the LGPL."+ ,""+ ,"----------------------------------------------------------------------------"+ ,""]++licenseText :: Text -> Text+licenseText name = staticLinkingException name <> T.unlines  ["                  GNU LESSER GENERAL PUBLIC LICENSE"  ,"                       Version 2.1, February 1999"  ,""
lib/Data/GI/CodeGen/Properties.hs view
@@ -23,8 +23,7 @@ import Data.GI.CodeGen.Haddock (addSectionDocumentation, writeHaddock,                                 RelativeDocPosition(DocBeforeSymbol)) import Data.GI.CodeGen.Inheritance (fullObjectPropertyList, fullInterfacePropertyList)-import Data.GI.CodeGen.SymbolNaming (lowerName, upperName,-                                     classConstraint, typeConstraint,+import Data.GI.CodeGen.SymbolNaming (lowerName, upperName, classConstraint,                                      hyphensToCamelCase, qualifiedSymbol,                                      callbackDynamicWrapper) import Data.GI.CodeGen.Type@@ -39,6 +38,7 @@    TGHash _ _ -> return "Hash"    TVariant -> return "Variant"    TParamSpec -> return "ParamSpec"+   TGClosure _ -> return "Closure"    TBasicType TInt -> case sizeOf (0 :: CInt) of                         4 -> return "Int32"                         n -> error ("Unsupported `gint' type length: " ++@@ -89,13 +89,14 @@ -- the type variables for the object and its value. attrType :: Property -> CodeGen ([Text], Text) attrType prop = do+  resetTypeVariableScope   isCallback <- typeIsCallback (propType prop)   if isCallback     then do       ftype <- foreignType (propType prop)       return ([], typeShow ftype)     else do-      (_,t,constraints) <- argumentType ['a'..'l'] $ propType prop+      (t,constraints) <- argumentType $ propType prop       return (constraints, t)  -- | Generate documentation for the given setter.@@ -120,7 +121,7 @@   writeHaddock DocBeforeSymbol (setterDoc n prop)   line $ setter <> " :: (" <> T.intercalate ", " constraints'            <> ") => o -> " <> t <> " -> m ()"-  line $ setter <> " obj val = liftIO $ setObjectProperty" <> tStr+  line $ setter <> " obj val = liftIO $ B.Properties.setObjectProperty" <> tStr            <> " obj \"" <> propName prop            <> if isNullable && (not isCallback)               then "\" (Just val)"@@ -141,7 +142,7 @@ genPropertyGetter getter n docSection prop = group $ do   isNullable <- typeIsNullable (propType prop)   let isMaybe = isNullable && propReadNullable prop /= Just False-  constructorType <- isoHaskellType (propType prop)+  constructorType <- inboundHaskellType (propType prop)   tStr <- propTypeStr $ propType prop   cls <- classConstraint n   let constraints = "(MonadIO m, " <> cls <> " o)"@@ -151,8 +152,8 @@       returnType = typeShow $ "m" `con` [outType]       getProp = if isNullable && not isMaybe                 then "checkUnexpectedNothing \"" <> getter-                         <> "\" $ getObjectProperty" <> tStr-                else "getObjectProperty" <> tStr+                         <> "\" $ B.Properties.getObjectProperty" <> tStr+                else "B.Properties.getObjectProperty" <> tStr   -- Some property getters require in addition a constructor, which   -- will convert the foreign value to the wrapped Haskell one.   constructorArg <-@@ -189,7 +190,7 @@   writeHaddock DocBeforeSymbol (constructorDoc prop)   line $ constructor <> " :: " <> pconstraints            <> t <> " -> IO (GValueConstruct o)"-  line $ constructor <> " val = constructObjectProperty" <> tStr+  line $ constructor <> " val = B.Properties.constructObjectProperty" <> tStr            <> " \"" <> propName prop            <> if isNullable && (not isCallback)               then "\" (Just val)"@@ -219,7 +220,7 @@                 else "(Nothing :: " <> nothingType <> ")"   line $ clear <> " :: (" <> T.intercalate ", " constraints            <> ") => o -> m ()"-  line $ clear <> " obj = liftIO $ setObjectProperty" <> tStr+  line $ clear <> " obj = liftIO $ B.Properties.setObjectProperty" <> tStr            <> " obj \"" <> propName prop <> "\" " <> nothing   export docSection clear @@ -322,8 +323,8 @@              then return "()"              else do                sOutType <- if isNullable && propReadNullable prop /= Just False-                           then typeShow . maybeT <$> isoHaskellType (propType prop)-                           else typeShow <$> isoHaskellType (propType prop)+                           then typeShow . maybeT <$> inboundHaskellType (propType prop)+                           else typeShow <$> inboundHaskellType (propType prop)                return $ if T.any (== ' ') sOutType                         then parenthesize sOutType                         else sOutType@@ -332,17 +333,7 @@   cppIf CPPOverloading $ do     cls <- classConstraint owner     inConstraint <- if writable || constructOnly-                    then do-                      inIsGO <- isGObject (propType prop)-                      isCallback <- typeIsCallback (propType prop)-                      hInType <- if isCallback-                                 then typeShow <$> foreignType (propType prop)-                                 else typeShow <$> haskellType (propType prop)-                      if inIsGO-                         then typeConstraint (propType prop)-                         else return $ "(~) " <> if T.any (== ' ') hInType-                                                 then parenthesize hInType-                                                 else hInType+                    then haskellTypeConstraint (propType prop)                     else return "(~) ()"     let allowedOps = (if writable                       then ["'AttrSet", "'AttrConstruct"]
lib/Data/GI/CodeGen/Signal.hs view
@@ -53,7 +53,7 @@     line $ "type " <> name' <> " ="     indent $ do       forM_ inArgsWithArrows $ \(arrow, arg) -> do-        ht <- haskellType (argType arg)+        ht <- inboundHaskellType (argType arg)         isMaybe <- wrapMaybe arg         let formattedType = if isMaybe                             then typeShow (maybeT ht)@@ -149,15 +149,16 @@   export (NamedSubsection SignalSection subsec) closure   writeHaddock DocBeforeSymbol closureDoc   group $ do-      line $ closure <> " :: " <> callback <> " -> IO Closure"-      line $ closure <> " cb = do"+      line $ closure <> " :: MonadIO m => " <> callback <> " -> m (GClosure "+                     <> callbackCType callback <> ")"+      line $ closure <> " cb = liftIO $ do"       indent $ do             wrapped <- genWrappedCallback cb "cb" callback isSignal             line $ callbackWrapperAllocator callback <> " " <> wrapped-                     <> " >>= newCClosure"+                     <> " >>= B.GClosure.newGClosure"   where     closureDoc :: Text-    closureDoc = "Wrap the callback into a `Closure`."+    closureDoc = "Wrap the callback into a `GClosure`."  -- Wrap a conversion of a nullable object into "Maybe" object, by -- checking whether the pointer is NULL.
lib/Data/GI/CodeGen/Struct.hs view
@@ -128,8 +128,8 @@                  then return Nothing                  else maybeNullConvert (fieldType field)   hType <- typeShow <$> if isJust nullConvert-                        then maybeT <$> isoHaskellType (fieldType field)-                        else isoHaskellType (fieldType field)+                        then maybeT <$> inboundHaskellType (fieldType field)+                        else inboundHaskellType (fieldType field)   fType <- typeShow <$> foreignType (fieldType field)    writeHaddock DocBeforeSymbol (getterDoc n field)@@ -254,8 +254,8 @@   embedded <- isEmbedded field   isNullable <- typeIsNullable (fieldType field)   outType <- typeShow <$> if not embedded && isNullable-                          then maybeT <$> isoHaskellType (fieldType field)-                          else isoHaskellType (fieldType field)+                          then maybeT <$> inboundHaskellType (fieldType field)+                          else inboundHaskellType (fieldType field)   inType <- if isPtr             then typeShow <$> foreignType (fieldType field)             else typeShow <$> haskellType (fieldType field)
lib/Data/GI/CodeGen/Transfer.hs view
@@ -42,6 +42,7 @@ basicFreeFn (TError) = Nothing basicFreeFn (TVariant) = Nothing basicFreeFn (TParamSpec) = Nothing+basicFreeFn (TGClosure _) = Nothing  -- Basic free primitives in the case that an error occured. This is -- run in the exception handler, so any type which we ref/allocate@@ -58,6 +59,10 @@ basicFreeFnOnError TParamSpec transfer =     return $ if transfer == TransferEverything              then Just "unrefGParamSpec"+             else Nothing+basicFreeFnOnError (TGClosure _) transfer =+    return $ if transfer == TransferEverything+             then Just "B.GClosure.unrefGClosure"              else Nothing basicFreeFnOnError t@(TInterface _) transfer = do   api <- findAPI t
lib/Data/GI/GIR/BasicTypes.hs view
@@ -63,5 +63,6 @@     | TGList Type      -- ^ GList     | TGSList Type     -- ^ GSList     | TGHash Type Type -- ^ GHashTable+    | TGClosure (Maybe Type) -- ^ GClosure containing the given API (if known)     | TInterface Name  -- ^ A reference to some API in the GIR       deriving (Eq, Show, Ord)
lib/Data/GI/GIR/Property.hs view
@@ -39,6 +39,7 @@   writable <- optionalAttr "writable" False parseBool   construct <- optionalAttr "construct" False parseBool   constructOnly <- optionalAttr "construct-only" False parseBool+  maybeNullable <- optionalAttr "nullable" Nothing (\t -> Just <$> parseBool t)   let flags = (if readable then [PropertyReadable] else [])               <> (if writable then [PropertyWritable] else [])               <> (if construct then [PropertyConstruct] else [])@@ -51,7 +52,6 @@                 , propTransfer = transfer                 , propDeprecated = deprecated                 , propDoc = doc-                -- No support in the GIR for nullability info-                , propReadNullable = Nothing-                , propWriteNullable = Nothing+                , propReadNullable = maybeNullable+                , propWriteNullable = maybeNullable                 }
lib/Data/GI/GIR/Type.hs view
@@ -100,6 +100,12 @@                  other -> parseError $ "Unsupported hash type: "                                        <> T.pack (show other) +-- | Parse a `GClosure` declaration.+parseClosure :: Parser Type+parseClosure = queryAttr "closure-type" >>= \case+                Just t -> (TGClosure . Just) <$> parseTypeName t+                Nothing -> return $ TGClosure Nothing+ -- | For GLists and GSLists there is sometimes no information about -- the type of the elements. In these cases we report them as -- pointers.@@ -116,18 +122,13 @@ parseFundamentalType "GLib" "Error" = return TError parseFundamentalType "GLib" "Variant" = return TVariant parseFundamentalType "GObject" "ParamSpec" = return TParamSpec+parseFundamentalType "GObject" "Closure" = parseClosure -- A TInterface type (basically, everything that is not of a known type). parseFundamentalType ns n = resolveQualifiedTypeName (Name ns n) --- | Parse information on a "type" element. Returns either a `Type`,--- or `Nothing` indicating that the name of the type in the--- introspection data was "none" (associated with @void@ in C).-parseTypeInfo :: Parser (Maybe Type)-parseTypeInfo = do-  typeName <- getAttr "name"-  if typeName == "none"-  then return Nothing-  else Just <$> case nameToBasicType typeName of+-- | Parse a type given as a string.+parseTypeName :: Text -> Parser Type+parseTypeName typeName = case nameToBasicType typeName of     Just b -> return (TBasicType b)     Nothing -> case T.split ('.' ==) typeName of                  [ns, n] -> parseFundamentalType ns n@@ -136,6 +137,16 @@                    parseFundamentalType ns n                  _ -> parseError $ "Unsupported type form: \""                                    <> typeName <> "\""++-- | Parse information on a "type" element. Returns either a `Type`,+-- or `Nothing` indicating that the name of the type in the+-- introspection data was "none" (associated with @void@ in C).+parseTypeInfo :: Parser (Maybe Type)+parseTypeInfo = do+  typeName <- getAttr "name"+  if typeName == "none"+  then return Nothing+  else Just <$> parseTypeName typeName  -- | Find the children giving the type of the given element. parseTypeElements :: Parser [Maybe Type]