packages feed

hls-graph 1.7.0.0 → 1.8.0.0

raw patch · 11 files changed

+86/−65 lines, 11 filesdep +unliftioPVP ok

version bump matches the API change (PVP)

Dependencies added: unliftio

API changes (from Hackage documentation)

+ Development.IDE.Graph.Database: shakeGetDatabaseKeys :: ShakeDatabase -> IO [(Key, Int)]
+ Development.IDE.Graph.Internal.Types: instance Control.Monad.IO.Unlift.MonadUnliftIO Development.IDE.Graph.Internal.Types.Action
- Development.IDE.Graph.Internal.Action: apply :: (RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value]
+ Development.IDE.Graph.Internal.Action: apply :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value)
- Development.IDE.Graph.Internal.Action: applyWithoutDependency :: (RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value]
+ Development.IDE.Graph.Internal.Action: applyWithoutDependency :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value)
- Development.IDE.Graph.Internal.Database: build :: forall key value. (RuleResult key ~ value, Typeable key, Show key, Hashable key, Eq key, Typeable value) => Database -> Stack -> [key] -> IO ([Key], [value])
+ Development.IDE.Graph.Internal.Database: build :: forall f key value. (Traversable f, RuleResult key ~ value, Typeable key, Show key, Hashable key, Eq key, Typeable value) => Database -> Stack -> f key -> IO (f Key, f value)
- Development.IDE.Graph.Rule: apply :: (RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value]
+ Development.IDE.Graph.Rule: apply :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value)
- Development.IDE.Graph.Rule: applyWithoutDependency :: (RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value]
+ Development.IDE.Graph.Rule: applyWithoutDependency :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value)

Files

hls-graph.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name:          hls-graph-version:       1.7.0.0+version:       1.8.0.0 synopsis:      Haskell Language Server internal graph API description:   Please see the README on GitHub at <https://github.com/haskell/haskell-language-server/tree/master/hls-graph#readme>@@ -61,7 +61,7 @@   hs-source-dirs:     src   build-depends:     , aeson-    , async+    , async >= 2.0     , base >=4.12 && <5     , bytestring     , containers@@ -81,6 +81,7 @@     , stm-containers     , time     , transformers+    , unliftio     , unordered-containers    if flag(embed-files)@@ -133,4 +134,5 @@     , tasty-hunit     , tasty-rerun     , text+    , unordered-containers   build-tool-depends: hspec-discover:hspec-discover -any
src/Development/IDE/Graph/Database.hs view
@@ -9,6 +9,7 @@     shakeRunDatabaseForKeys,     shakeProfileDatabase,     shakeGetBuildStep,+    shakeGetDatabaseKeys,     shakeGetDirtySet,     shakeGetCleanKeys     ,shakeGetBuildEdges) where@@ -79,3 +80,8 @@     keys <- getDatabaseValues db     let ress = mapMaybe (getResult . snd) keys     return $ sum $ map (length . getResultDepsDefault [] . resultDeps) ress++-- | Returns an approximation of the database keys,+--   annotated with how long ago (in # builds) they were visited+shakeGetDatabaseKeys :: ShakeDatabase -> IO [(Key, Int)]+shakeGetDatabaseKeys (ShakeDatabase _ _ db) = getKeysAndVisitAge db
src/Development/IDE/Graph/Internal/Action.hs view
@@ -24,6 +24,8 @@ import           Control.Monad.IO.Class import           Control.Monad.Trans.Class import           Control.Monad.Trans.Reader+import           Data.Foldable                           (toList)+import           Data.Functor.Identity import           Data.IORef import           Development.IDE.Graph.Classes import           Development.IDE.Graph.Internal.Database@@ -111,19 +113,19 @@     Action $ lift $ finally (runReaderT (fromAction a) v) b  apply1 :: (RuleResult key ~ value, ShakeValue key, Typeable value) => key -> Action value-apply1 k = head <$> apply [k]+apply1 k = runIdentity <$> apply (Identity k) -apply :: (RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value]+apply :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value) apply ks = do     db <- Action $ asks actionDatabase     stack <- Action $ asks actionStack     (is, vs) <- liftIO $ build db stack ks     ref <- Action $ asks actionDeps-    liftIO $ modifyIORef ref (ResultDeps is <>)+    liftIO $ modifyIORef ref (ResultDeps (toList is) <>)     pure vs  -- | Evaluate a list of keys without recording any dependencies.-applyWithoutDependency :: (RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value]+applyWithoutDependency :: (Traversable f, RuleResult key ~ value, ShakeValue key, Typeable value) => f key -> Action (f value) applyWithoutDependency ks = do     db <- Action $ asks actionDatabase     stack <- Action $ asks actionStack
src/Development/IDE/Graph/Internal/Database.hs view
@@ -7,11 +7,13 @@ {-# LANGUAGE RankNTypes                 #-} {-# LANGUAGE RecordWildCards            #-} {-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE TupleSections              #-} {-# LANGUAGE TypeFamilies               #-}-{-# LANGUAGE TupleSections #-}  module Development.IDE.Graph.Internal.Database (newDatabase, incDatabase, build, getDirtySet, getKeysAndVisitAge) where +import           Prelude                              hiding (unzip)+ import           Control.Concurrent.Async import           Control.Concurrent.Extra import           Control.Concurrent.STM.Stats         (STM, atomically,@@ -30,19 +32,21 @@ import           Data.HashSet                         (HashSet) import qualified Data.HashSet                         as HSet import           Data.IORef.Extra+import           Data.List.NonEmpty                   (unzip) import           Data.Maybe import           Data.Traversable                     (for) import           Data.Tuple.Extra-import           Debug.Trace (traceM)+import           Debug.Trace                          (traceM) import           Development.IDE.Graph.Classes import           Development.IDE.Graph.Internal.Rules import           Development.IDE.Graph.Internal.Types import qualified Focus import qualified ListT import qualified StmContainers.Map                    as SMap-import           System.Time.Extra                    (duration, sleep) import           System.IO.Unsafe+import           System.Time.Extra                    (duration, sleep) + newDatabase :: Dynamic -> TheRules -> IO Database newDatabase databaseExtra databaseRules = do     databaseStep <- newTVarIO $ Step 0@@ -78,13 +82,17 @@             in KeyDetails status' rdeps -- | Unwrap and build a list of keys in parallel build-    :: forall key value . (RuleResult key ~ value, Typeable key, Show key, Hashable key, Eq key, Typeable value)-    => Database -> Stack -> [key] -> IO ([Key], [value])+    :: forall f key value . (Traversable f, RuleResult key ~ value, Typeable key, Show key, Hashable key, Eq key, Typeable value)+    => Database -> Stack -> f key -> IO (f Key, f value) -- build _ st k | traceShow ("build", st, k) False = undefined build db stack keys = do-    (ids, vs) <- runAIO $ fmap unzip $ either return liftIO =<<-            builder db stack (map Key keys)-    pure (ids, map (asV . resultValue) vs)+    built <- runAIO $ do+        built <- builder db stack (fmap Key keys)+        case built of+          Left clean  -> return clean+          Right dirty -> liftIO dirty+    let (ids, vs) = unzip built+    pure (ids, fmap (asV . resultValue) vs)     where         asV :: Value -> value         asV (Value x) = unwrapDynamic x@@ -93,7 +101,7 @@ --  If none of the keys are dirty, we can return the results immediately. --  Otherwise, a blocking computation is returned *which must be evaluated asynchronously* to avoid deadlock. builder-    :: Database -> Stack -> [Key] -> AIO (Either [(Key, Result)] (IO [(Key, Result)]))+    :: Traversable f => Database -> Stack -> f Key -> AIO (Either (f (Key, Result)) (IO (f (Key, Result)))) -- builder _ st kk | traceShow ("builder", st,kk) False = undefined builder db@Database{..} stack keys = withRunInIO $ \(RunInIO run) -> do     -- Things that I need to force before my results are ready@@ -199,7 +207,7 @@         calcAgeStatus _         = Nothing     return $ mapMaybe (secondM calcAgeStatus) dbContents --- | Returns ann approximation of the database keys,+-- | Returns an approximation of the database keys, --   annotated with how long ago (in # builds) they were visited getKeysAndVisitAge :: Database -> IO [(Key, Int)] getKeysAndVisitAge db = do@@ -317,7 +325,7 @@     | Spawn {justWait :: !(IO ())}  fmapWait :: (IO () -> IO ()) -> Wait -> Wait-fmapWait f (Wait io) = Wait (f io)+fmapWait f (Wait io)  = Wait (f io) fmapWait f (Spawn io) = Spawn (f io)  waitOrSpawn :: Wait -> IO (Either (IO ()) (Async ()))
src/Development/IDE/Graph/Internal/Rules.hs view
@@ -46,7 +46,7 @@ runRule     :: TheRules -> Key -> Maybe BS.ByteString -> RunMode -> Action (RunResult Value) runRule rules key@(Key t) bs mode = case Map.lookup (typeOf t) rules of-    Nothing -> liftIO $ errorIO "Could not find key"+    Nothing -> liftIO $ errorIO $ "Could not find key: " ++ show key     Just x  -> unwrapDynamic x key bs mode  runRules :: Dynamic -> Rules () -> IO (TheRules, [Action ()])
src/Development/IDE/Graph/Internal/Types.hs view
@@ -27,17 +27,18 @@ import           Data.Dynamic import qualified Data.HashMap.Strict           as Map import           Data.HashSet                  (HashSet, member)+import qualified Data.HashSet                  as Set import           Data.IORef+import           Data.List                     (intercalate) import           Data.Maybe import           Data.Typeable import           Development.IDE.Graph.Classes import           GHC.Generics                  (Generic) import qualified ListT-import           StmContainers.Map             (Map) import qualified StmContainers.Map             as SMap+import           StmContainers.Map             (Map) import           System.Time.Extra             (Seconds)-import qualified Data.HashSet as Set-import Data.List (intercalate)+import           UnliftIO                      (MonadUnliftIO)   unwrapDynamic :: forall a . Typeable a => Dynamic -> a@@ -64,7 +65,7 @@ -- ACTIONS  newtype Action a = Action {fromAction :: ReaderT SAction IO a}-    deriving newtype (Monad, Applicative, Functor, MonadIO, MonadFail, MonadThrow, MonadCatch, MonadMask)+    deriving newtype (Monad, Applicative, Functor, MonadIO, MonadFail, MonadThrow, MonadCatch, MonadMask, MonadUnliftIO)  data SAction = SAction {     actionDatabase :: !Database,
test/ActionSpec.hs view
@@ -1,21 +1,22 @@-{-# LANGUAGE OverloadedLists #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}  module ActionSpec where -import Control.Concurrent.STM-import Development.IDE.Graph (shakeOptions)-import Development.IDE.Graph.Database (shakeNewDatabase, shakeRunDatabase)-import Development.IDE.Graph.Internal.Action (apply1)-import Development.IDE.Graph.Internal.Types-import Development.IDE.Graph.Rule-import Example-import qualified StmContainers.Map as STM-import Test.Hspec-import System.Time.Extra (timeout)+import           Control.Concurrent.STM+import qualified Data.HashSet                          as HashSet+import           Development.IDE.Graph                 (shakeOptions)+import           Development.IDE.Graph.Database        (shakeNewDatabase,+                                                        shakeRunDatabase)+import           Development.IDE.Graph.Internal.Action (apply1)+import           Development.IDE.Graph.Internal.Types+import           Development.IDE.Graph.Rule+import           Example+import qualified StmContainers.Map                     as STM+import           System.Time.Extra                     (timeout)+import           Test.Hspec  spec :: Spec spec = do@@ -54,7 +55,7 @@           apply1 theKey       res `shouldBe` [True]       Just KeyDetails {..} <- atomically $ STM.lookup (Key (Rule @())) databaseValues-      keyReverseDeps `shouldBe` [Key theKey]+      keyReverseDeps `shouldBe` HashSet.fromList [Key theKey]     it "rethrows exceptions" $ do       db <- shakeNewDatabase shakeOptions $ do         addRule $ \(Rule :: Rule ()) old mode -> error "boom"
test/DatabaseSpec.hs view
@@ -1,20 +1,21 @@-{-# LANGUAGE OverloadedLists #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE OverloadedLists     #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-} module DatabaseSpec where -import Control.Concurrent.STM-import Development.IDE.Graph (shakeOptions)-import Development.IDE.Graph.Database (shakeNewDatabase, shakeRunDatabase)-import Development.IDE.Graph.Internal.Action (apply1)-import Development.IDE.Graph.Internal.Types-import Development.IDE.Graph.Rule-import Example-import qualified StmContainers.Map as STM-import Test.Hspec-import System.Time.Extra (timeout)+import           Control.Concurrent.STM+import           Development.IDE.Graph                 (shakeOptions)+import           Development.IDE.Graph.Database        (shakeNewDatabase,+                                                        shakeRunDatabase)+import           Development.IDE.Graph.Internal.Action (apply1)+import           Development.IDE.Graph.Internal.Types+import           Development.IDE.Graph.Rule+import           Example+import qualified StmContainers.Map                     as STM+import           System.Time.Extra                     (timeout)+import           Test.Hspec  spec :: Spec spec = do
test/Example.hs view
@@ -1,16 +1,16 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveAnyClass      #-}+{-# LANGUAGE DeriveGeneric       #-}+{-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeApplications    #-}+{-# LANGUAGE TypeFamilies        #-} module Example where -import Development.IDE.Graph-import Development.IDE.Graph.Rule-import Development.IDE.Graph.Classes-import GHC.Generics-import Type.Reflection (typeRep)+import           Development.IDE.Graph+import           Development.IDE.Graph.Classes+import           Development.IDE.Graph.Rule+import           GHC.Generics+import           Type.Reflection               (typeRep)  data Rule a = Rule     deriving (Eq, Generic, Hashable, NFData)
test/Main.hs view
@@ -1,7 +1,7 @@ import qualified Spec-import Test.Tasty-import Test.Tasty.Hspec-import Test.Tasty.Ingredients.Rerun (defaultMainWithRerun)+import           Test.Tasty+import           Test.Tasty.Hspec+import           Test.Tasty.Ingredients.Rerun (defaultMainWithRerun)  main :: IO () main = testSpecs Spec.spec >>= defaultMainWithRerun . testGroup "tactics"
test/RulesSpec.hs view
@@ -1,6 +1,6 @@ module RulesSpec where -import Test.Hspec+import           Test.Hspec  spec :: Spec spec = do